本笔记参考该该作者帖子,自己学习,提升使用
dispatch_apply类似一个for循环,会在指定的dispatch queue中运行block任务n次,如果队列是并发队列,则会并发执行block任务,dispatch_apply是一个同步调用,block任务执行n次后才返回。
简单的使用方法:
并发队列
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(5, queue, ^(size_t i) {
NSLog(@"%@我开始执行 %zu times",[NSThread currentThread],i+1);
});
NSLog(@"done");
输出结果:
[3545:1502823] <NSThread: 0x125e0c240>{number = 1, name = main}我开始执行 1 times
[3545:1502839] <NSThread: 0x125e06070>{number = 2, name = (null)}我开始执行 2 times
[3545:1502839] <NSThread: 0x125e06070>{number = 2, name = (null)}我开始执行 4 times
[3545:1502839] <NSThread: 0x125e06070>{number = 2, name = (null)}我开始执行 5 times
[3545:1502823] <NSThread: 0x125e0c240>{number = 1, name = main}我开始执行 3 times
[3553:1504850] done
串行队列
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_apply(5, queue, ^(size_t i) {
NSLog(@"%@我开始执行 %zu times",[NSThread currentThread],i+1);
});
NSLog(@"done");
输出结果:
[3535:1501629] <NSThread: 0x13ce03880>{number = 1, name = main}我开始执行 1 times
[3535:1501629] <NSThread: 0x13ce03880>{number = 1, name = main}我开始执行 2 times
[3535:1501629] <NSThread: 0x13ce03880>{number = 1, name = main}我开始执行 3 times
[3535:1501629] <NSThread: 0x13ce03880>{number = 1, name = main}我开始执行 4 times
[3535:1501629] <NSThread: 0x13ce03880>{number = 1, name = main}我开始执行 5 times
[3553:1504850] done
总结:
dispatch_apply在串行队列中按照顺序执行,完全没有意义。在并发队列中创建了N个任务,如果是在异步队列中则异步执行(由打印结果显示),但并非所有任务不开辟线程,也有在主线程中完成的。最后由输出的“done”字符串可以看出但done一定会输出在最后的位置,因为dispatch_apply函数会等待所有的处理结束
在某些场景下使用dispatch_apply会对性能有很大的提升,比如你的代码需要以每个像素为基准来处理计算image图片。同时dispatch apply能够避免一些线程爆炸的情况发生(创建很多线程)
//危险,可能导致线程爆炸以及死锁
for (int i = 0; i < 999; i++){
dispatch_async(q, ^{...});
}
dispatch_barrier_sync(q, ^{});
// 较优选择, GCD 会管理并发
dispatch_apply(999, q, ^(size_t i){...});
应用场景:
如果我们从服务器获取一个数组的数据,那么我们可以使用该方法从而快速的批量字典转模型。
代码示例如下:
NSArray *dictArray = nil;//存放从服务器返回的字典数组
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
dispatch_apply(dictArray.count, queue, ^(size_t index){
//字典转模型
});
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"主线程更新");
});
});
网友评论