GCD 常用总结

2017-05-11  本文已影响31人  panzhangbao

什么是GCD?

GCD的优势

主队列

    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(mainQueue, ^{
        NSLog(@"异步主队列");
    });

全局队列

    /** long identifier
     * {
     *    DISPATCH_QUEUE_PRIORITY_HIGH
     *    DISPATCH_QUEUE_PRIORITY_DEFAULT
     *    DISPATCH_QUEUE_PRIORITY_LOW
     *    DISPATCH_QUEUE_PRIORITY_BACKGROUND
     * }
     */
    dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_sync(defaultQueue, ^{
        NSLog(@"同步全局队列");
    });
    ```

# 创建队列
      
- 我们还可以根据个人具体情况创建属于自己的队列。
- 创建队列有串行队列和并行队列两种,其中串行队列只能单线程操作,并行队列可以多线程操作。
- 而它们的执行方式也有两种:同步执行和异步执行。

// 1. 创建串行队列
dispatch_queue_t createSerialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
// 同步执行
dispatch_sync(createSerialQueue, ^{
NSLog(@"创建串行同步队列");
});
// 2. 创建并行队列
dispatch_queue_t createConcurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
// 异步执行
dispatch_async(createConcurrentQueue, ^{
NSLog(@"创建并行队列");
});

// 挂起队列
dispatch_suspend(createSerialQueue);
// 重挂队列
dispatch_resume(createSerialQueue);
// 变更优先级
dispatch_set_target_queue(createSerialQueue, defaultQueue);
```

单例操作 - 只执行一次的代码块

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"只运行一次哦");
    });

延时加载

    // 延时 2 秒
    double delayInSeconds = 2.0;
    // 相对时间
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds);
    // 绝对时间
//    popTime = [self getDispatchTimeByDate:[NSDate date]];
     dispatch_after(popTime, mainQueue, ^{
         NSLog(@"延时 2 s 执行");
     });

/*
 *  获取绝对时间
 */
- (dispatch_time_t)getDispatchTimeByDate:(NSDate *)date
{
    double second = 0.0;
    struct timespec timespec;

    NSTimeInterval interval = [date timeIntervalSinceNow];
    
    timespec.tv_sec = second;
    timespec.tv_nsec = modf(interval, &second) * NSEC_PER_SEC;
    
    return dispatch_walltime(&timespec, 0);
}

队列组 - 多个依赖关系

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_group_async(group, defaultQueue, ^{
        NSLog(@"执行调度组1");
    });
    dispatch_group_async(group, defaultQueue, ^{
        NSLog(@"执行调度组2");
    });
    dispatch_group_async(group, defaultQueue, ^{
        NSLog(@"执行调度组3");
    });
    // 只要属于 Dispatch Group 的处理尚未执行结束,就会一直等待,中途不能取消
//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    dispatch_group_notify(group, mainQueue, ^{
        NSLog(@"后期添加的 group 队列,在 group 最后执行");
    });
    ```
# 单个依赖关系 - 推荐使用
dispatch_async(defaultQueue, ^{
    NSLog(@"先执行我");
});
// 在前面的任务执行结束后它才执行,而且它后面的任务等待其执行完后再执行
dispatch_barrier_async(defaultQueue, ^{
    NSLog(@"我是中间执行者哦");
});
dispatch_async(defaultQueue, ^{
    NSLog(@"最后执行者");
});
# 同步信号量

- dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,
- dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1,根据这样的原理,我们便可以快速的创建一个并发控制来同步任务和有限资源访问控制
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
for (int i = 0; i < 10; i++)
{
    // 申请信号量
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_group_async(group, defaultQueue, ^{
        NSLog(@"申请信号量:%i",i);
        sleep(2);
        // 释放信号量
        dispatch_semaphore_signal(semaphore);
        NSLog(@"释放信号量:%i", i);
    });
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
# 多个添加队列
// 注意,添加的这 10 个队列同步执行,并等待 queue 全部处理执行结束
unsigned int applyTimes = 5;
dispatch_apply(applyTimes, defaultQueue, ^(size_t i) {
    NSLog(@"添加的队列:%zu", i);
});
**个人建议:苹果自己开发或者多人协作开发用 GCD 就足够了,当设计到多个依赖关系时,可以考虑使用 NSOperation 。**
# 参考
[GCD使用三部曲之:基本用法](http://www.jianshu.com/p/d56064507fb8)
上一篇 下一篇

猜你喜欢

热点阅读