我正在从我的应用程序中的 CDN 异步下载图像(在 UICollectionView 中)。每次我运行它,不同的图像将无法加载。大约 22 个中的 1-3 个。有时(很少)它们都加载。但关键是它并不一致。发生了什么是在这一行:
NSData *fileData = [NSData dataWithContentsOfURL:location];
fileData 是间歇性的 nil 。奇怪的是,来自 NSURLSessionDownloadTask 的 error 也是 nil 。这是完整的方法:
+ (void) downloadFileAsynchronouslyWithUrlNSURL *)fileUrl andCallbackvoid (^)(NSData* fileData, NSError* error))callback {
NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithURL:fileUrl completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error != nil) {
NSLog(@"ERROR: %@", error.localizedDescription);
callback(nil, error);
}
else {
NSData *fileData = [NSData dataWithContentsOfURL:location];
if (fileData != nil) {
callback(fileData, nil);
}
else {
// Getting this intermittently
NSError *err = [self errorFromString"downloaded file was nil!"];
callback(nil, err);
}
}
});
}];
[downloadTask resume];
}
我已经记录了状态码,它总是 200。
这让我很困惑。有什么想法吗?
Best Answer-推荐答案 strong>
您应该确保将文件同步移动到本地(或将其加载到 NSData )。当您从此 downloadTaskWithURL 完成 block 返回时,该文件将被删除。您正尝试从 dispatch_async 中读取此文件,这会在从文件中获取数据和操作系统为您删除此临时文件之间引入竞争条件。
所以,你可以试试这样的:
+ (void) downloadFileAsynchronouslyWithUrlNSURL *)fileUrl andCallbackvoid (^)(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 ,这样可以避免这个问题。当我们试图减少峰值内存使用和/或使用后台 session 时,我们通常会使用下载任务,但这些情况都不适用于这里。
关于ios - NSURLSessionDownloadTask 偶尔会导致 nil 数据,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/48217076/
|