菜鸟教程小白 发表于 2022-12-13 03:54:12

ios - NSURLSessionDownloadTask 偶尔会导致 nil 数据


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

<pre><code>NSData *fileData = ;
</code></pre>

<p><code>fileData</code> 是间歇性的 <code>nil</code> 。奇怪的是,来自 <code>NSURLSessionDownloadTask</code> 的 <code>error</code> 也是 <code>nil</code>。这是完整的方法:</p>

<pre><code>+ (void) downloadFileAsynchronouslyWithUrl:(NSURL *)fileUrl andCallback:(void (^)(NSData* fileData, NSError* error))callback {
    NSURLSessionDownloadTask *downloadTask = [ downloadTaskWithURL:fileUrl completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
      dispatch_async(dispatch_get_main_queue(), ^{
            if (error != nil) {
                NSLog(@&#34;ERROR: %@&#34;, error.localizedDescription);
                callback(nil, error);
            }
            else {
                NSData *fileData = ;
                if (fileData != nil) {
                  callback(fileData, nil);
                }
                else {
                  // Getting this intermittently
                  NSError *err = ;
                  callback(nil, err);
                }
            }
      });
    }];
    ;
}
</code></pre>

<p>我已经记录了状态码,它总是 200。</p>

<p>这让我很困惑。有什么想法吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您应该确保将文件同步移动到本地(或将其加载到 <code>NSData</code>)。当您从此 <code>downloadTaskWithURL</code> 完成 block 返回时,该文件将被删除。您正尝试从 <code>dispatch_async</code> 中读取此文件,这会在从文件中获取数据和操作系统为您删除此临时文件之间引入竞争条件。</p>

<p>所以,你可以试试这样的:</p>

<pre><code>+ (void) downloadFileAsynchronouslyWithUrl:(NSURL *)fileUrl andCallback:(void (^)(NSData* fileData, NSError* error))callback {
    NSURLSessionDownloadTask *downloadTask = [ downloadTaskWithURL:fileUrl completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
      if (error != nil) {
            NSLog(@&#34;ERROR: %@&#34;, error.localizedDescription);
            dispatch_async(dispatch_get_main_queue(), ^{
                callback(nil, error);
            });
      }
      else {
            NSData *fileData = ;
            dispatch_async(dispatch_get_main_queue(), ^{
                if (fileData != nil) {
                  callback(fileData, nil);
                }
                else {
                  // Getting this intermittently
                  NSError *err = ;
                  callback(nil, err);
                }
            });
      }
    }];
    ;
}
</code></pre>

<p>或者,您可以考虑使用 <code>URLSessionDataTask</code>,这样可以避免这个问题。当我们试图减少峰值内存使用和/或使用后台 session 时,我们通常会使用下载任务,但这些情况都不适用于这里。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - NSURLSessionDownloadTask 偶尔会导致 nil 数据,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/48217076/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/48217076/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - NSURLSessionDownloadTask 偶尔会导致 nil 数据