美文网首页Fuck iOS EveryDay
iOS开发系列-线程同步dispatch_apply

iOS开发系列-线程同步dispatch_apply

作者: lltree | 来源:发表于2016-07-04 17:27 被阅读2743次

    本笔记参考该该作者帖子,自己学习,提升使用

    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(@"主线程更新");
            });
        });
    

    相关文章

      网友评论

        本文标题:iOS开发系列-线程同步dispatch_apply

        本文链接:https://www.haomeiwen.com/subject/ldzcjttx.html