《Objective-C 高级编程》学习笔记3-GCD


狮子头镇楼编程

《Objective-C 高级编程》学习笔记1-内存管理

《Objective-C 高级编程》学习笔记2-Blocksbash


1   什么是 GCD

将应用程序中记述的线程管理用的代码在系统级中实现。开发者只须要定义想要执行的任务并追加到适当的 Dispatch Queue 中,GCD就能生成必要的线程并计划执行任务。async


2   GCD 的 API

dispatch_async(queue, ^{
    /* * 想执行的任务 */
})复制代码

该源码使用 Block 语法“定义想执行的任务”,经过 dispatch_async 函数“追加”赋值在变量 queue 的“Dispatch Queue中”。函数

2.一、Dispatch Queue

Dispatch Queue:执行处理的等待队列。有两种:oop

  • Serial Dispatch Queue,串行队列
  • Concurrent Dispatch Queue,并行队列

2.二、dispatch_queue_create

//建立串行队列
dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.gcd.mySerialDispatchQueue", NULL);
dispatch_async(mySerialDispatchQueue, ^{
    //在串行队列中执行Block
});
    
//建立并行队列
dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.gcd.myConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myConcurrentDispatchQueue, ^{
    //在并行队列中执行Block
});
复制代码

2.三、Main Dispatch Queue / Global Dispatch Queue

这是系统标准提供的 Dispatch Queue

2.3.一、Main Dispatch Queue
post

主线程执行的的 Dispatch Queue,由于主线程只有一个,因此它必定是串行队列

追加到 Main Dispatch Queue 的处理在主线程的 RunLoop 中执行。所以用户界面的操做等一些必须在主线程中执行的处理追加到 Main Dispatch Queue 中使用。学习

2.3.二、Global Dispatch Queueui

是全部应用程序都可以使用的并行队列,它有四个优先级。


///主队列获取
dispatch_queue_t mdq = dispatch_get_main_queue();
    
//全局队列,执行优先级:高
dispatch_queue_t gdq_high = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
//全局队列,执行优先级:中
dispatch_queue_t gdq_default = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//全局队列,执行优先级:低
dispatch_queue_t gdq_low = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
//全局队列,执行优先级:后台
dispatch_queue_t gdq_background = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

复制代码

2.四、dispatch_set_target_queue

dispatch_queue_create 函数生成的 Dispatch Queue 无论是 串行队列 仍是 并行队列,都使用与默认优先级 Global Dispatch Queue 相同执行优先级的线程。可以使用 dispatch_set_target_queue 函数变动 Dispatch Queue 的执行优先级。spa

2.五、dispatch_after

可以使用 dispatch_after 执行指定时间后执行的处理。注意:dispatch_after 函数并非在指定时间后执行处理,而只是在指定时间追加处理到 Dispatch Queue 。线程

dispatch_time_t dt = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
dispatch_after(dt, dispatch_get_main_queue(), ^{
    //执行操做的block
});复制代码

2.六、Dispatch Group

在追加到 Dispatch Queue 中的多个处理所有结束后想执行结束处理的时候使用。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
    
dispatch_group_async(group, queue, ^{ NSLog(@"blk0"); });
dispatch_group_async(group, queue, ^{ NSLog(@"blk1"); });
dispatch_group_async(group, queue, ^{ NSLog(@"blk2"); });
dispatch_group_async(group, queue, ^{ NSLog(@"blk3"); });
    
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"done"); });
复制代码

2.七、dispatch_sync

  • async 意味着 “非同步”,dispatch_async 函数不作任何等待。
  • sync 意味着 “同步”,dispatch_sync 函数会将指定的 Block “同步” 追加到指定的 Dispatch Queue 中。在追加 Block 结束以前,dispatch_sync 函数会一直等待。

dispatch_sync 使用不当会形成一个很严重的问题:死锁。

dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"同步任务在 %@ 执行", [NSThread currentThread]);
});

//一、主线程正在执行主队列的任务;
//二、一个同步任务过来了,因而,主线程当即等待;
//三、同步任务在等主线程当前任务完成,然而主线程在等待这个同步任务执行;
//四、因而就形成了相互等待的状况。
复制代码

2.八、dispatch_once

dispatch_once 函数是保证在应用程序执行中只执行以此指定处理的API。如初始化单例。

+ (instancetype)share {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}复制代码


3   GCD 实现

3.一、Dispatch Queue

GCD 的 Dispatch Queue 很是方便,实现 GCD 须要:

  • 用于管理追加的 Block 的 C语言层实现的 FIFO 队列。
  • Atomic 函数中实现的用于排他控制的轻量级信号。
  • 用于管理线程的C语言层实现的一些容器。
相关文章
相关标签/搜索