t4n*_*hpt 24 multithreading grand-central-dispatch ios swift
我想同时下载一些文件,例如100个文件.所以我决定将我的下载线程添加到调度队列,GCD将调整同时运行的线程数.
这里的问题是:块dispatch_async将立即完成,因为task将在另一个线程上运行.因此,如果urls长度为100,它将立即创建100个线程.
var queueDownloadTask = dispatch_queue_create("downloadQueue", nil)
for url in urls {
    dispatch_async(queueDownloadTask) {
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let fileTransferSession = NSURLSession(configuration: config)
        let task = fileTransferSession.downloadTaskWithURL(url, completionHandler: { (responseUrl, response, error) -> Void in
            println("completed")
        })
        task.resume()
    }
}
如何配置块dispatch_async以等待下载任务完成?我不想使用dispatch_semaphore,因为它只允许同时运行一个下载任务.
Aec*_*Liu 35
在Swift3中,
func executeMultiTask() {
     //1. Create group
     let taskGroup = DispatchGroup()
     //2. Enter group
     taskGroup.enter()
     myTask1.execute(completeHandler: {
         // ...
         //3. Leave group
         taskGroup.leave() //< balance with taskGroup.enter()
     })
     /* Add more tasks ...
     //2. Enter group
     taskGroup.enter()
     myTask2.execute(completeHandler: {
         //3. Leave group
         defer {
            // Use `defer` to make sure, `leave()` calls are balanced with `enter()`.
            taskGroup.leave() 
         }
         // ... more
     })
     */
     //4. Notify when all task completed at main thread queue.
     taskGroup.notify(queue: .main) { 
         // All tasks are done.
         // ...   
     }
}
jtb*_*des 30
为了扩展Abhinav的答案,你应该:
dispatch_group_create()创建一个组.dispatch_group_enter(group)在开始每个下载任务之前调用.dispatch_group_leave(group)在任务的完成处理程序内部调用.dispatch_group_notify(group, queue, ^{ ... })将所有任务完成时将执行的块排入队列.你可以在这篇文章中看到一个例子.
(顺便说一下,dispatch_async连续100 秒创建100个线程并不是真的.系统仍然可以控制用于满足队列的线程数.但是,您的代码不会等待任何任务到在它返回之前完成,也不会尝试在完成的多个任务之间进行同步.)
一个用于下载多文件的工作 Objective-c 示例
- (void) downloadFiles: (NSMutableArray *) fileArray : (NSString *)destParentDir{
    dispatch_group_t serviceGroup = dispatch_group_create();
    for (id fileInfo in fileArray) {
        dispatch_group_enter(serviceGroup);
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *fileName = [fileInfo valueForKey:@"name"];
        //Create SubDirs if needed, note that you need to exclude file name for the dirsString :)
        //[fileManager createDirectoryAtPath:dirsString withIntermediateDirectories:true attributes:nil error:NULL];
        //Download file
        NSURL  *url = [NSURL URLWithString:@"YOUR_FILE_URL"];
        NSData *urlData = [NSData dataWithContentsOfURL:url];
        if(urlData)
        {
            NSString  *localPath = [NSString stringWithFormat:@"%@/%@", destParentDir, fileName];
            [urlData writeToFile:localPath atomically:YES];
        }
        dispatch_group_leave(serviceGroup);
    }
    dispatch_group_notify(serviceGroup, dispatch_get_main_queue(),^{
        NSLog(@"Complete files download");
    });
}
| 归档时间: | 
 | 
| 查看次数: | 12951 次 | 
| 最近记录: |