一、Dispatch Queue的分类
按照执行处理的方式分为两类:
种类 | 说明 |
---|---|
Serial(串行执行) | 等待队列中正在执行的任务结束 |
Concurrent(并行执行) | 不等待队列中正在执行的任务结束 |
二、Dispatch Queue的生成方式
1、dispatch_queue_create
Declaration
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
Parameters
label
A string label to attach to the queue to uniquely identify it in debugging tools such as Instruments, sample, stackshots, and crash reports. Because applications, libraries, and frameworks can all create their own dispatch queues, a reverse-DNS naming style (com.example.myqueue) is recommended. This parameter is optional and can be NULL.
标记queue的名称,通常使用应用程序ID的逆序追加自定义的名称,崩溃日志里这个参数会显得非常有用。
attr
In macOS 10.7 and later or iOS 4.3 and later, specify DISPATCH_QUEUE_SERIAL (or NULL) to create a serial queue or specify DISPATCH_QUEUE_CONCURRENT to create a concurrent queue. In earlier versions, you must specify NULL for this parameter.
DISPATCH_QUEUE_CONCURRENT
|DISPATCH_QUEUE_SERIAL
Serial Dispatch Queue的创建示例代码
dispatch_queue_t serialQueue = dispatch_queue_create("com.custom.mSerialQueue", NULL);
或者
dispatch_queue_t serialQueue = dispatch_queue_create("com.custom.mSerialQueue", DISPATCH_QUEUE_SERIAL);
Concurrent Dispatch Queue的创建示例代码
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.custom.mConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
2、获取系统提供的Dispatch Queue
Main Dispatch Queue
示例代码
dispatch_queue_t queue = dispatch_get_main_queue();
Global Dispatch Queue
种类 | Dispatch Queue种类 | 说明 |
---|---|---|
DISPATCH_QUEUE_PRIORITY_HIGH | Serial Queue | 主线程执行 |
DISPATCH_QUEUE_PRIORITY_HIGH | Concurrent Queue | 执行优先级最高 2 |
DISPATCH_QUEUE_PRIORITY_DEFAULT | Concurrent Queue | 默认优先级 0 |
DISPATCH_QUEUE_PRIORITY_LOW | Concurrent Queue | 执行优先级低 -2 |
DISPATCH_QUEUE_PRIORITY_BACKGROUND | Concurrent Queue | 后台执行 |
示例代码
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_get_global_queue
方法的第二个参数flags
预留以后可能使用,一般传值0即可。
三、dispatch_set_target_queue
包括两个作用
变更执行的优先级指定执行的层次,多个并发执行的串行队列,通过此方法设置同一个串行队列,在原本多个串行队列上并发执行的任务在新的串行队列上一次只执行一个任务
以上内容获取自《Objective-C高级编程.pdf》,但是从官方针对方法dispatch_set_target_queue第二个参数queue的描述来看其实并不是更改了优先级和执行层次,而是把原来队列里待执行的任务放到了target queue中执行,所以最终可以实现上面两个目的。
Declaration
void dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue);
Parameters
object
从方法的作用来看,object不能指定为主线程(主线程没有优先级一说,同时也没有执行层次区别),第二是系统全局定义的线程(都定义好了的岂是你说改就能改的)
queue
The new target queue for the object. The queue is retained, and the previous one, if any, is released. This parameter cannot be NULL.
四、dispatch_after
延时执行处理
五、dispatch_group
用于监听多个并发任务全部完成状态
六、dispatch_barrier_async
比dispatch_async高级的地方是可以等待已追加到队列的任务执行完成,在通过dispatch_barrier_async追加的任务执行完成后再执行后续追加的其他并行任务。多用于安全地提高操作数据库或文件的效率,串行访问数据库或文件确实可以避免数据竞争的问题,但是性能较低。
七、dispatch_async和dispatch_sync的区别
async和sync的区别在于将任务追加到队列的方式,async采用异步追加方式,sync采用同步追加方式。由于采用dispatch_sync的方式追加任务会等待当前任务执行结束,所以有两种情况必会造成死锁,如下:
- 当前执行上下文是主线程的环境同步往主线程追加任务
dispatch_queue_t mianQueue = dispatch_get_main_queue();
///情形一
dispatch_async(mianQueue, ^{
NSLog(@"-----main queue");
dispatch_sync(mianQueue, ^{
NSLog(@"-----main queue");
});
});
///情形二
dispatch_sync(mianQueue, ^{
NSLog(@"-----main queue");
});
- 在同一个串行执行队列里同步追加任务
dispatch_queue_t oneQueue = dispatch_queue_create("com.test.oneQueue", NULL);
dispatch_async(oneQueue, ^{
dispatch_sync(oneQueue, ^{
NSLog(@"dispatch_sync(oneQueue");
});
});