- 1.dispatch_apply函數(shù)作用:把一項任務提交到隊列中多次執(zhí)行,具體是串行執(zhí)行還是并行執(zhí)行由隊列本身決定
注意:dispatch_apply不會立即返回,在執(zhí)行完畢后才會返回,是同步的調用
void dispatch_apply(size_t iterations, dispatch_queue_t queue,
DISPATCH_NOESCAPE void (^block)(size_t));
參數(shù) :
size_t iterations: 執(zhí)行的次數(shù)
dispatch_queue_t queue: 提交的隊列
block 執(zhí)行的任務
size_t block中每次任務執(zhí)行的索引
那么,何時使用這個函數(shù)呢?從它的功能不難看出,如果我們可以把不相關的循環(huán)提交到后臺線程并行執(zhí)行,并且循環(huán)任務調度到后臺執(zhí)行的效率提高,能抵消掉隊列調度本身的開銷,那么效率會顯著提高。
例子:從一個文件夾中移動文檔到另一個文件夾的操作
分析:移動文件這種操作應該在后臺執(zhí)行的,移動完成后如果需要通知用戶,可以在dispatch_apply代碼后面操作
因為dispatch_apply會阻塞主線程,而下文又與dispatch_apply的執(zhí)行結果無關,所以可以在異步隊列中掉dispatch_apply,然后執(zhí)行完成后進行通知
NSString *sourceFile = @"/Users/mofeini/Desktop/toImage"; // 源文件目錄
NSString *targetFile = @"/Users/mofeini/Desktop/to"; // 目標文件路面
NSArray *sourceFileSubPaths = [[NSFileManager defaultManager] subpathsAtPath:sourceFile];
NSInteger count = sourceFileSubPaths.count;
// 開啟子線程和主線程一起并發(fā)完成任務
dispatch_apply(count, dispatch_get_global_queue(0, 0), ^(size_t i) {
NSString *filePath = [targetFile stringByAppendingPathComponent:sourceFileSubPaths[i]];
NSString *toFilePath = [targetFile stringByAppendingPathComponent:sourceFileSubPaths[i]];
[[NSFileManager defaultManager] moveItemAtPath:filePath toPath:toFilePath error:nil];
NSLog(@"%ld, 當前線程%@", i, [NSThread currentThread]);
});
// 文件全部移動完成后通知用戶
NSLog(@"文件已全部移動完畢");
打印結果
>索引== 2, 當前線程<NSThread: 0x600000078640>{number = 3, name = (null)}
索引==1, 當前線程<NSThread: 0x608000076880>{number = 4, name = (null)}
索引== 0, 當前線程<NSThread: 0x610000074280>{number = 1, name = main}
索引==3, 當前線程<NSThread: 0x6000000785c0>{number = 5, name = (null)}
文件已全部移動完畢