【问题标题】:AFNetworking/NSURLSession takes long to create more than 100 tasks to download filesAFNetworking/NSURLSession耗时长创建100多个任务下载文件
【发布时间】: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 秒,直到创建所有任务.

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

【问题讨论】:

    标签: ios afnetworking nsurlsession


    【解决方案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 次,这会很长。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多