我正在编写一个iPad应用程序,我在其中异步加载多层建筑的数据。我已经设置了NSNotifications,以便在完成所有楼层的数据加载后提醒用户。
在ChildViewController(弹出式VC)中按下加载按钮时,每个楼层的数据加载都会循环启动
从ParentViewController启动ChildViewController。
我在ChildViewController中添加了一个名为“dataloaded”的通知的观察者 并设置处理函数childDataLoaded来处理通知。
由于ChildViewController可能在数据加载完成之前被解除,我还在ParentViewController中设置了观察者和处理程序(parentDataLoaded)来处理相同的“数据加载”通知。
我在AppDelegate中实现了数据加载函数'parseAndSaveData'。单击ChildViewController按钮时,将调用parseAndSaveData。它将楼层标识符(NSString)作为参数。它调用Web服务来获取该层的数据并将此数据加载到数据库中。 Web服务很快,但将数据添加到sqllite数据库需要更长的时间(我正在使用Core数据)。因此,我使用dispatch_asynch调用调用此dataload部分(因为这是最耗时的部分)。
完成后的dataload部分发布“dataloaded”通知。
我希望此通知调用ChildViewController或ParentViewController中的处理程序(发布通知时处于活动状态)
我遇到的问题是通知是不可预测的,我只看到一个处理程序(ChildViewController中的处理程序)被调用,并且只调用其中一个楼层,尽管所有楼层都成功加载。
对于上述设计和实施或替代方案的任何建议都将非常感谢!
为来自@Samuel的dispatch_group建议添加代码
Confirm action on my popup VC kicks off the following…
creates a a GCD dispatch_group, floorDataGroup
creates a GCD dispatch_queue, floorDataQueue, using dispatch_get_global_queue
with default priority
loops over floors in building and for each floor {
dispatch_group_async(floorDataGroup, floorDataQueue, ^{
// start dispatch_group_async block
//gets rooms details for the building and floor as follows:
Calls webservice (using AFNetworking Library) to get room details,
which on success executes a block
( ^{
Parses the XML, extracts room data
Inserts room data into Core Data/sqllite table
}); //end web service success block
}); //end dispatch_group_async block
} //end loop over each floor
dispatch_group_notify(floorDataGroup, floorDataQueue, ^{
//start dispatch_group_nbotify block
create alert (UIAlert) with message “All floors loaded”
and an OK button to dismiss the alert
[alert show]
}
答案 0 :(得分:1)
我会考虑使用来自Apple GCD Docs
的NSOperationQueue ...GCD不仅限于系统级应用程序,但在将其用于更高级别的应用程序之前,您应该考虑Cocoa中提供的类似功能(通过NSOperation和块对象)是否更易于使用或更适合您的需要。有关详细信息,请参阅“并发编程指南”。
具体看看使用NSBlockOperation。您可以使用addExecutionBlock:在单独的执行块中添加每个数据请求。然后使用setCompletionBlock:设置完成块。确保在主线程上触发完成块。
如果您必须使用GCD,我建议您查看groups。
stackoverflow相关问题,答案很好: