AFNetworking/NSURLSession耗时长创建100多个任务下载文件

Posted

技术标签:

【中文标题】AFNetworking/NSURLSession耗时长创建100多个任务下载文件【英文标题】:AFNetworking/NSURLSession takes long to create more than 100 tasks to download files 【发布时间】:2017-08-11 15:15:40 【问题描述】:

我的应用程序需要下载许多文件,我使用 for 循环来创建下载任务。以下方法是AFNetworking提供的方法。

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
                                         progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock
                                      destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
__block NSURLSessionDownloadTask *downloadTask = nil;
url_session_manager_create_task_safely(^
    downloadTask = [self.session downloadTaskWithRequest:request];
);

[self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler];

return downloadTask;

我的代码是这样的:

for (NSInteger i = 0; i<= 500; i++) 
    NSMutableURLRequest *request = array[i];

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:downloadProgress destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) 
        return destinationPath;
     completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) 
        completionBlock(filePath,error);
    ];

    [downloadTask resume];

问题是

downloadTask = [self.session downloadTaskWithRequest:request];

这条线需要比较长的时间,也就是说如果执行500次,大概需要5~6秒。

我的应用会弹出一个 alertView 询问用户是否下载,如果他们点击 Yes,它将执行类似于 for 循环的操作,因此 UI 将停留在那里 5~6 秒,直到创建所有任务.

我不确定我是否正确,或者是否有其他方法可以进行批量下载。 谁能帮我?谢谢。

【问题讨论】:

【参考方案1】:

您应该在不同的线程上下载(在后台运行)。这样,用户将继续顺利使用该应用程序。试试下面的代码:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)  // in half a second...
    //do your download here

希望这会有所帮助!

【讨论】:

我可以使用 GCD 来做到这一点吗? cgd是什么意思?【参考方案2】:

我建议您转换到使用NSURLSessionAFHTTPSessionManager。旧的AFHTTPRequestOperationManager 是基于NSURLConnection,但现在不推荐使用NSURLConnection。而且,事实上,AFNetworking 3.0 已经完全淘汰了AFHTTPRequestOperationManager

所以,AFHTTPSessionManager 下载方法可能如下所示:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

for (NSInteger i = 0; i < urlArray.count; i++) 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlArray[i]]];
    NSURLSessionTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress) 
        [self.delegate downloadProgression:downloadProgress.fractionCompleted * 100.0];
     destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) 
        return [NSURL fileURLWithPath:[self.documentDirectory getDownloadContentPath:contentPaths[i]]];
     completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) 
        NSLog(@"File downloaded to: %@", filePath);
        NSLog(@"Error: %@" error.localizedDescription);
    ];
    [task resume];

【讨论】:

这正是我现在使用的。问题是 NSURLSessionTask *task = [manager downloadTaskWithRequest:request 这需要很长时间才能创建任务,如果循环很大,比如说 500 次,这会很长。

以上是关于AFNetworking/NSURLSession耗时长创建100多个任务下载文件的主要内容,如果未能解决你的问题,请参考以下文章

下载许多文件时 AFNetworking / NSURLSession 超时