Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 后台获取和异步UICollectionView_Ios_Asynchronous_Ios7_Uicollectionview - Fatal编程技术网

Ios 后台获取和异步UICollectionView

Ios 后台获取和异步UICollectionView,ios,asynchronous,ios7,uicollectionview,Ios,Asynchronous,Ios7,Uicollectionview,我正在尝试在应用程序中实现iOS后台获取API。该应用程序从服务器下载JSON,调用-[UICollectionView重载数据],并针对每个单元格,在-collectionView:cellForItemAtIndexPath:中异步下载图像 在我的初始实现中,在调用reloadData之后,我会将系统传递的完成处理程序调用到application:performFetchWithCompletionHandler。多任务视图中的应用程序快照将显示空单元格,因为图像还没有下载。为了解决这个问题

我正在尝试在应用程序中实现iOS后台获取API。该应用程序从服务器下载JSON,调用
-[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的子类中——这将帮助您处理阻塞、丢弃多个请求等情况,或者处理所有这些类型的情况

因此,我不想写内联块,而是转向一个操作队列,它看起来像是一个提升,但实际上使它更易于正确处理