博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OC_GCD的基本使用
阅读量:6604 次
发布时间:2019-06-24

本文共 2399 字,大约阅读时间需要 7 分钟。

简述

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 就会分离执行了。

转载于:https://juejin.im/post/5bcedab651882577e830a132

你可能感兴趣的文章
display:table-cell的应用
查看>>
在micropython固件中增加自己的模块
查看>>
【数学】数论进阶-常见数论函数
查看>>
第一轮复习Servlet day04
查看>>
Babel下的ES6兼容性与规范
查看>>
【iOS开发】视图控制器加载和卸载时的几个函数
查看>>
python——装饰器
查看>>
事件的绑定
查看>>
.htaccess内容
查看>>
关于表单重复提交问题
查看>>
port 22: Connection refused
查看>>
java中关键字volatile的作用(转载)
查看>>
基础查询语句
查看>>
Linux 硬链接、软链接
查看>>
ORACLE PL/SQL编程之六: 把过程与函数说透
查看>>
[.Net线程处理系列]专题五:线程同步——事件构造
查看>>
Welcom To My Blog
查看>>
windows 下使clion支持c++11操作记录
查看>>
组件里传值到父级
查看>>
201521123009 《Java程序设计》第13周学习总结
查看>>