Ios 后台获取和异步UICollectionView
我正在尝试在应用程序中实现iOS后台获取API。该应用程序从服务器下载JSON,调用Ios 后台获取和异步UICollectionView,ios,asynchronous,ios7,uicollectionview,Ios,Asynchronous,Ios7,Uicollectionview,我正在尝试在应用程序中实现iOS后台获取API。该应用程序从服务器下载JSON,调用-[UICollectionView重载数据],并针对每个单元格,在-collectionView:cellForItemAtIndexPath:中异步下载图像 在我的初始实现中,在调用reloadData之后,我会将系统传递的完成处理程序调用到application:performFetchWithCompletionHandler。多任务视图中的应用程序快照将显示空单元格,因为图像还没有下载。为了解决这个问题
-[UICollectionView重载数据]
,并针对每个单元格,在-collectionView:cellForItemAtIndexPath:
中异步下载图像
在我的初始实现中,在调用reloadData
之后,我会将系统传递的完成处理程序调用到application:performFetchWithCompletionHandler
。多任务视图中的应用程序快照将显示空单元格,因为图像还没有下载。为了解决这个问题,我在重新加载数据后删除了完成处理程序调用,编写了一个小结构来跟踪下载了哪些单元格的图像,只有在下载了一定数量的图像后,我才会调用完成处理程序
我使用视图控制器上的completionBlock
属性来重新加载图像。应用程序委托设置该属性,然后调用该视图控制器上的reload
方法,该方法随后调用其完成处理程序属性。我看起来像这样:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
WSViewController *viewController = (WSViewController *)navController.topViewController;
viewController.completionBlock = ^(BOOL success, BOOL newData) {
if (!success) {
completionHandler(UIBackgroundFetchResultFailed);
} else if (success) {
if (newData) {
completionHandler(UIBackgroundFetchResultNewData);
} else {
completionHandler(UIBackgroundFetchResultNoData);
}
}
};
[viewController reload];
}
在测试期间,我发现以相对快速的顺序执行后台提取会导致不调用完成处理程序。这很容易解释,因为completionBlock
属性被覆盖,旧的属性不会被调用
因此,我删除了该属性,并决定在代码中始终传递完成处理程序-reload
现在是-reloadWithCompletionBlock:
等
但现在我被困在如何在App Delegate中实现这一点上。视图控制器有一个委托,其方法之一,-(void)didFinishDownloadingImages
,由App委托实现这就是我要调用完成处理程序的地方。但是我不能,因为如果不将它存储在属性中,就无法访问完成处理程序,这就违背了我当初这样做的原因
关于如何解决这个问题有什么想法吗?使用NSOperationQueue并将代码块移动到NSOperation的子类中——这将帮助您处理阻塞、丢弃多个请求等情况,或者处理所有这些类型的情况 因此,我不想写内联块,而是转向一个操作队列,它看起来像是一个提升,但实际上使它更易于正确处理