GCD 的使用
来源:互联网 发布:linux select c代码 编辑:程序博客网 时间:2024/05/16 07:06
GCD : 纯 C 语言的 API
GCD 核心
1.任务:执行什么操作
同步:永远只在当前线程
上 从上往下,依次执行
执行,这个就叫做同步
异步:永远不在当前的线程
上执行,它跑到别的线程上面去执行。
总结:同步方法 永远在当前线程上执行,所以没有开辟线程的能力。
异步方法,因为要在别的线程上去执行,所以它具有开辟线程的能力。
当遇到主队列
,这个奇葩的时候,它就不起作用
2.队列:用来存放任务
作用:将相同的任务
放在同一个队列中,方便管理
a.串行队列:
加入到里面的任务是一个一个有顺序的调度的。
串行队列,同步任务 特点:有顺序的执行,并且不会开辟新线程,就在当前线程执行 应用场景:FMDB,它为什么要设计成串行队列,同步任务,为了保证数据的安全
/** * 串行队列,同步任务执行 */- (void)selrilSync { // 1.创建任务 void (^task1)() = ^() { NSLog(@"task1----%@", [NSThread currentThread]); }; void (^task2)() = ^() { NSLog(@"task2----%@", [NSThread currentThread]); }; void (^task3)() = ^() { NSLog(@"task3----%@", [NSThread currentThread]); }; // 2.创建队列 串行队列 dispatch_queue_t serial = dispatch_queue_create("cn.jingcheng", DISPATCH_QUEUE_SERIAL); //将任务添加带队列中 dispatch_sync(serial, task1); dispatch_sync(serial, task2); dispatch_sync(serial, task3);}
串行队列,异步任务 特点:有顺序的执行,并且在开辟的新的线程中执行,并且只开一条线程!!! 应用场景:耗时操作,并且有严格先后顺序 去付费网站上,下载片 登录--->付费--->下载
/** * 串行队列,异步执行 */- (void)serialAsync { void (^task1)() = ^() { NSLog(@"task1----%@", [NSThread currentThread]); }; void (^task2)() = ^() { NSLog(@"task2----%@", [NSThread currentThread]); }; void (^task3)() = ^() { NSLog(@"task3----%@", [NSThread currentThread]); }; dispatch_queue_t serial = dispatch_queue_create("cn.jingcheng", NULL); dispatch_async(serial, task1); dispatch_async(serial, task2); dispatch_async(serial, task3);}
b.并发队列:
特点:
任务可以同时执行,这样可以提高程序的运行效率.
并发队列,同步任务 特点:没有开辟新线程,同时是按照顺序 应用场景:开发中几乎不用
/** * 并发队列,同步任务执行 */- (void)concurrentSync { void (^task1)() = ^() { NSLog(@"task1----%@", [NSThread currentThread]); }; void (^task2)() = ^() { NSLog(@"task2----%@", [NSThread currentThread]); }; void (^task3)() = ^() { NSLog(@"task3----%@", [NSThread currentThread]); }; dispatch_queue_t concurrent = dispatch_queue_create("cn.jingcheng", DISPATCH_QUEUE_CONCURRENT); dispatch_sync(concurrent, task1); dispatch_sync(concurrent, task2); dispatch_sync(concurrent, task3);}
并发队列,异步任务 特点:会开线程,开N条,表示不固定,因为我们的线程循环利用的功能 没有顺序. 应用场景: 比如下载多部片
/** * 并发队列,异步任务执行 */- (void)concurrentAsync { void (^task1)() = ^() { NSLog(@"task1----%@", [NSThread currentThread]); }; void (^task2)() = ^() { NSLog(@"task2----%@", [NSThread currentThread]); }; void (^task3)() = ^() { NSLog(@"task3----%@", [NSThread currentThread]); }; dispatch_queue_t concurrent = dispatch_queue_create("cn.jingcheng", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrent, task1); dispatch_async(concurrent, task2); dispatch_async(concurrent, task3);}
c.全局队列:
和并发队列,执行效果一样,只是说,并发队列,需要我们程序员,自己创建
而全局队列,是由于系统提供
特点: 任务可以同时执行,这样可以提高程序的运行效率. 全局队列,同步任务 特点:没有开辟新线程,同时是按照顺序 应用场景:开发中几乎不用 全局队列,异步任务 特点:会开线程,开N条,表示不固定,因为我们的线程循环利用的功能 没有顺序. 应用场景: 比如下载多部片
/** * 全局队列 */- (void)globalQueue{ dispatch_queue_t global = dispatch_get_global_queue(0, 0); //全局队列同步执行任务 dispatch_sync(global, ^{ NSLog(@"%@",[NSThread currentThread]); }); //全局队列异步执行任务 dispatch_sync(global, ^{ NSLog(@"%@",[NSThread currentThread]); });}
d.主队列(奇葩
):
特点:
它永远在主线程工作,这个是苹果给开发人员,提供,回到主线程做事的一种机制
主队列,同步任务 特点:主队列,只有在`主线程空闲`的时候,才能调度里面的任务 造成死锁 主队列,异步任务 应用场景: 回到主线程做事,一般是做和UI相关的工作.
/** * 主队列 */- (void)mainQueue { dispatch_queue_t mainQ = dispatch_get_main_queue(); //全局队列同步执行任务 (死锁) dispatch_sync(mainQ, ^{ NSLog(@"%@", [NSThread currentThread]); }); //全局队列异步执行任务 dispatch_sync(mainQ, ^{ NSLog(@"%@", [NSThread currentThread]); });}
总结:任务的优先级比队列优先级高,所以我们在队列和任务的各种组合的时候,首先要看我们的任务. 1.开不开线程,由任务决定 异步才有开辟线程的能力,同步没有开辟线程的能力 异步是在其它线程上执行,同步,在当前线程上执行. iOS 8.0 之后,GCD 能够开启非常多的线程 iOS 7.0 以及之前,GCD 通常只会开启 5~6 条线程 2.在开发中,主队列比较奇葩,主队列,就是苹果提供给我们,快速回到主线程的种实现机制.
开发中队列的选择
多线程的目的:将耗时的操作放在后台执行!
串行队列,只开一条线程,所有任务顺序执行
队列组
有这么1种需求
首先:分别异步执行2个耗时的操作
其次:等2个异步操作都执行完毕后,再回到主线程执行操作
如果想要快速高效地实现上述需求,可以考虑用队列组
//创建队列组 dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 执行1个耗时的异步操作 }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 执行1个耗时的异步操作 }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 等前面的异步操作都执行完毕后,回到主线程... });
- (void)cacheStatusImage:(NSArray *)array and:(FinishedArray)finish { if (array.count == 0) { finish(nil, nil); return; } //创建线程组 dispatch_group_t group = dispatch_group_create(); for (XFStatues *statues in array) { NSArray *urls = statues.danLoadPicUrl; if (urls.count != 1) { continue; } for (NSURL *imageUrl in urls) { //操作开始 dispatch_group_enter(group); [[SDWebImageManager sharedManager] downloadImageWithURL:imageUrl options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { NSLog(@"单张图片下载完成"); //操作结束 dispatch_group_leave(group); }]; } } //线程组下载图片任务全部完成,主线程完成所有图片下载回调 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"所有图片下载完成"); finish(nil, array); });}
如果任务有先后执行顺序的要求
效率低 -> 执行慢 -> “省电”
有的时候,用户其实不希望太快!例如使用 3G 流量,”省钱”
并发队列,会开启多条线程,所有任务不按照顺序执行
如果任务没有先后执行顺序的要求
效率高 -> 执行快 -> “费电”
WIFI,包月
实际开发过程中开辟线程数
WIFI 线程数 6 条
3G / 4G 移动开发的时候,2~3条,再多会费电费钱!
- 多线程GCD的使用
- GCD的使用.
- GCD的使用
- 多线程GCD的使用
- 多线程GCD的使用
- iOS GCD的使用
- GCD的使用
- 多线程GCD的使用
- 多线程GCD的使用
- 多线程GCD的使用
- GCD的使用
- 多线程GCD的使用
- GCD的使用
- 多线程GCD的使用
- gcd的使用
- GCD的简单使用
- GCD的基本使用
- GCD的使用
- 【数据结构与算法】二 数组反转 reverse
- 交互式分析系统
- LEEDCODE 13 Roman to Integer (JAVA题解)
- android audio buffer 分析
- Struts2之入门
- GCD 的使用
- audioflinger 分析
- 数字相加等于2048c++源代码
- NumPy学习
- audiomixer分析
- 认识jQuery
- Swift笔记 使用CocoaPods来添加开源库
- Atitit.跨语言系统服务管理器api兼容设计
- audiopolicy分析