OC_GCD的基本使用

简述

GCD 为苹果推出的多核编程解决方案,它不仅能够自动利用多个核心处理数据,还能够自动管理生命周期,不需要程序猿手动管理。在日常的编程中十分常用。

创建队列

使用 GCD 首先需要创建或获取一个队列,可以使用 dispatch_queue_create

  • 创建一个队列,具体代码:

    dispatch_queue_t queue = dispatch_queue_create("SERIALQUEUE", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue = dispatch_queue_create("CONCURRENTQUEUE", DISPATCH_QUEUE_CONCURRENT);
    复制代码

    第一个参数为队列的唯一标识符,第二个参数表示该队列是并发队列还是串行队列。

    • DISPATCH_QUEUE_SERIAL : 表示串行队列

    • DISPATCH_QUEUE_CONCURRENT : 表示并发队列

  • 获取一个队列,具体代码:

    // 获取主队列
    dispatch_queue_t queue = dispatch_get_main_queue(); 
    // 获取全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    复制代码

    获取全局并发队列中的第一个参数表示队列的优先级,填入 DISPATCH_QUEUE_PRIORITY_DEFAULT 即可,第二个参数 0 即可。

创建任务

GCD创建任务分为两种:

  • 同步任务
  • 异步任务

创建方式分别如下:

// 同步任务
dispatch_sync(queue, ^{
    // code
});
// 异步任务
dispatch_async(queue, ^{
    // code
});
复制代码

同步和异步的区别是,异步允许开启新的线程,而同步不允许。串行和并发的区别是,串行只开启一条线程,并发能开启一条以上的线程。这就导致了:

  • 同步 + 并发 : 只开启一条线程,任务按顺序进行
  • 同步 + 串行 : 只有一条线程,任务按顺序进行
  • 异步 + 并发 : 开启多条线程,任务同时进行
  • 异步 + 串行 : 只有一条线程,任务按顺序进行

主队列 + 同步会造成死锁,如以下代码。

dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"1");
dispatch_sync(queue, ^{
   NSLog(@"2");
});
NSLog(@"3");
复制代码

以上代码只会输出 1 不会输出 2 ,3。

至于主队列 + 异步相当于串行 + 异步,只有一条线程,任务按顺序进行。全局并发队列与普通并发队列类似不再赘述。

GCD线程间的通信

试想这种场景,异步请求数据并且加载完 model 后,现在想回到主线程用更新好的 model 刷新视图。这个时候就要用到线程之间的通信。实现起来很简单,只需要在任务代码后再异步给主线程添加一个任务即可。如:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(queue, ^{
    // code 
    // 回到主线程
    dispatch_async(dispatch_get_main_queue(), ^{
        // code
    });
});
复制代码

GCD其他用法

dispatch_after 延迟执行

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // code
}
复制代码

其中的代码会在大约5秒后执行,为什么用大约,因为实际上不是很精确,但是对于延迟几秒执行代码,这个方法还是非常好用的。

dispatch_once 单次执行

static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // code
});
复制代码

内部的代码只会执行一次,并且是线程安全的。这个方法经常被用来编写单例使用,如:

// 单例
+ (instancetype)shareInstance {
    static Class * object = nil;
    static dispatch_once_t onceTocken;
    dispatch_once(&onceTocken, ^{
        object = [Class new];
    });
    return object;
}
复制代码

dispatch_barrier_async 栅栏任务

在两个异步任务中添加栅栏任务,能够将两者分开执行,而栅栏任务在两者之间执行。 使用方法如下:

dispatch_async(queue, ^{
        // code1
    });
dispatch_barrier_async(queue, ^{
        // code
    });
dispatch_async(queue, ^{
        // code2
    });
复制代码

这样使用后,code1 和 code2 就会分离执行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值