NSURLSessionDownloadTask偶尔会导致零数据

时间:2018-01-11 22:50:01

标签: ios objective-c asynchronous

我是从我的应用程序中的CDN异步下载图像(在UICollectionView中)。每次运行时,都会无法加载不同的图像。 22个中的大约1-3个。有时(很少)它们都会加载。但重点是它并不一致。发生了什么事情就是这一行:

new_row = [item._values['header_title1'], item.values['header_title2'], item._values['found_item']

NSData *fileData = [NSData dataWithContentsOfURL:location]; 是间歇性fileData。奇怪的是,nil中的error也是NSURLSessionDownloadTask。这是完整的方法:

nil

我已经记录了状态代码,它总是200.

令我困惑的是什么可能导致这种情况。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您应该确保将文件同步移动到本地(或将其加载到NSData)。从此downloadTaskWithURL完成块返回时,文件将被删除。并且您正试图从dispatch_async内部读取此文件,这会在抓取文件中的数据和为您删除此临时文件的操作系统之间引入竞争条件。

所以,你可能会尝试类似的东西:

+ (void) downloadFileAsynchronouslyWithUrl:(NSURL *)fileUrl andCallback:(void (^)(NSData* fileData, NSError* error))callback {
    NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithURL:fileUrl completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"ERROR: %@", error.localizedDescription);
            dispatch_async(dispatch_get_main_queue(), ^{
                callback(nil, error);
            });
        }
        else {
            NSData *fileData = [NSData dataWithContentsOfURL:location];
            dispatch_async(dispatch_get_main_queue(), ^{
                if (fileData != nil) {
                    callback(fileData, nil);
                }
                else {
                    // Getting this intermittently
                    NSError *err = [self errorFromString:@"downloaded file was nil!"];
                    callback(nil, err);
                }
            });
        }
    }];
    [downloadTask resume];
}

或者,您可以考虑使用URLSessionDataTask,这可以避免此问题。当我们尝试减少峰值内存使用量和/或使用后台会话时,我们通常会使用下载任务,但这些情况都不适用于此。