GCD慢慢整理

来源:互联网 发布:玛士达编程用软件 编辑:程序博客网 时间:2024/06/06 12:46
/** 凡是函数名中带有create\copy\new\retain等字眼, 都应该在不需要使用这个数据的时候进行release GCD的数据类型在ARC环境下不需要再做release CF(Core Foundation)的数据类型在ARC\MRC环境下都需要再做release */

1. 队列类型

串行队列:一次只能处理一个任务。(FIFO)一行代码执行完才能执行下一行代码。
并行队列:可以同时处理多个任务。

串行队列

// 第一个参数:队列名随便写,方便调试区别队列// 第二个参数:一般用NULL(也就是DISPATCH_QUEUE_SERIAL)/**#define DISPATCH_QUEUE_SERIAL #define DISPATCH_QUEUE_CONCURRENTDISPATCH_QUEUE_SERIAL串行队列,遵循先进先出原则DISPATCH_QUEUE_CONCURRENT这个比较特殊,创建的是自定义并行队列*/
dispatch_queue_t queue = dispatch_queue_create("队列名方便调试区别", NULL);

主队列(也是串行队列的一种)

// (添加到主队列中的任务,都会自动放到主线程中去执行。)// 主队列一般运行一些需要与主线程同步的一些短时任务。dispatch_queue_t queue = dispatch_get_main_queue();

并发队列(全局队列)

在不得以的情况下可以用dispatch_queue_create创建(串行队列有介绍),但一般我们都要用系统预定义的并行队列。

 // 第一个参数是优先级:一般用DISPATCH_QUEUE_PRIORITY_DEFAULT/**#define DISPATCH_QUEUE_PRIORITY_HIGH        2#define DISPATCH_QUEUE_PRIORITY_DEFAULT     0#define DISPATCH_QUEUE_PRIORITY_LOW         (-2)#define DISPATCH_QUEUE_PRIORITY_BACKGROUND  INT16_MIN*/// 第二个参数留着将来可能有用,默认为0 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  

获取当前队列

// 如果在队列执行任务中调用,返回执行此任务的队列;如果在主线程中调用,将返回主队列;如果在一般线程(非主线程线程非队列执行任务)中调用,返回全局队列。  dispatch_queue_t queue = dispatch_get_current_queue();

2. 线程同步与异步

同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。

同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
所以,要我请你吃饭就用同步的方法,要请我吃饭就用异步的方法,这样你可以省钱。

举个例子 打电话时同步 发消息是异步

线程与队列组合6种(2 X 3 = 6)(李明杰老师的视频整理的)

dispatch_sync (同步,不具备开启线程的能力)

/** *  sync -- 串行队列 *  会不会创建线程:不会 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) */- (void)syncSerialQueue{    // 创建一个串行队列    dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);    // 将 任务 添加到 串行队列 中 同步 执行    dispatch_sync(queue, ^{        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);    });}
/** *  sync -- 主队列(不能用---会卡死) */- (void)syncMainQueue{    NSLog(@"syncMainQueue----begin--");    // 1.主队列(添加到主队列中的任务,都会自动放到主线程中去执行)    dispatch_queue_t queue = dispatch_get_main_queue();    // 2.添加 任务 到主队列中 异步 执行    dispatch_sync(queue, ^{        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);    });    NSLog(@"syncMainQueue----end--");}// 主队列任务队列:->syncMainQueue()->dispatch_sync(queue, ^{})// 但是实际上是应该执行dispatch_sync(queue, ^{}),陷入死循环
/** *  sync -- 并发队列 *  会不会创建线程:不会 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) *  并发队列失去了并发的功能 */- (void)syncGlobalQueue{    // 获得全局的并发队列    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    // 将 任务 添加到 全局并发队列 中 同步 执行    dispatch_sync(queue, ^{        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);    });}

dispatch_async(异步,具备开启线程的能力)

/** *  sync -- 并发队列 *  会不会创建线程:不会 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) *  并发队列失去了并发的功能 */- (void)syncGlobalQueue{    // 获得全局的并发队列    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    // 将 任务 添加到 全局并发队列 中 同步 执行    dispatch_sync(queue, ^{        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);    });}
/** *  sync -- 并发队列 *  会不会创建线程:不会 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) *  并发队列失去了并发的功能 */- (void)syncGlobalQueue{    // 获得全局的并发队列    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    // 将 任务 添加到 全局并发队列 中 同步 执行    dispatch_sync(queue, ^{        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);    });    dispatch_sync(queue, ^{        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);    });}
/** *  async -- 并发队列(最常用) *  会不会创建线程:会,一般同时开多条 *  任务的执行方式:并发执行 */- (void)asyncGlobalQueue{    // 获得全局的并发队列    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    // 将 任务 添加 全局队列 中去 异步 执行    dispatch_async(queue, ^{        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);    });    dispatch_async(queue, ^{        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);    });}

3. 队列组(dispatch_group_async)

可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。

dispatch_group_t group = dispatch_group_create();dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_group_async(group, queue, ^{        [NSThread sleepForTimeInterval:1];         NSLog(@"group1");       });    dispatch_group_async(group, queue, ^{         [NSThread sleepForTimeInterval:2];          NSLog(@"group2");        });    dispatch_group_async(group, queue, ^{          [NSThread sleepForTimeInterval:3];        NSLog(@"group3");        });     dispatch_group_notify(group, dispatch_get_main_queue(), ^{             NSLog(@"update UI");       });

4. 其它使用

线程通信

// 一般异步并行下载图片,然后到主线程刷新界面 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_queue_t mainQueue = dispatch_get_main_queue();    dispatch_async(globalQueue, ^{        NSLog(@"donwload---%@", [NSThread currentThread]);        // 1.子线程下载图片        // 2.回到主线程设置图片        dispatch_async(mainQueue, ^{            NSLog(@"setting---%@ %@", [NSThread currentThread], image);        });    });

单例实现

 static NSObject *object = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        object = [[NSObject alloc] init];    });

延时实现

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{         NSLog(@"[%s]%d", __func__, __LINE__);    });
0 0
原创粉丝点击