iOS多线程GCD详解
2016-02-29 14:20
453 查看
iOS多线程GCD详解
我们在这里复习下GCD。
1.什么是GCD?
GCD全称Grand Central Dispatch,我们通俗的翻译叫牛逼的中心调度。
2.我们用GCD干什么?
通过 GCD,开发者不用再直接跟线程打交道了,只需要向队列中添加代码块即可,GCD 在后端管理着一个线程池。GCD 不仅决定着你的代码块将在哪个线程被执行,它还根据可用的系统资源对这些线程进行管理。这样可以将开发者从线程管理的工作中解放出来,通过集中的管理线程,来缓解大量线程被创建的问题。GCD 带来的另一个重要改变是,作为开发者可以将工作考虑为一个队列,而不是一堆线程,这种并行的抽象模型更容易掌握和使用。
首先,系统提供给你一个叫做 主队列(main queue) 的特殊队列。和其它串行队列一样,这个队列中的任务一次只能执行一个。然而,它能保证所有的任务都在主线程执行,而主线程是唯一可用于更新 UI 的线程。这个队列就是用于发生消息给 UIView 或发送通知的。
系统同时提供给你好几个并发队列。它们叫做 全局调度队列(Global Dispatch Queues) 。目前的四个全局队列有着不同的优先级:background、low、default 以及 high。要知道,Apple 的 API 也会使用这些队列,所以你添加的任何任务都不会是这些队列中唯一的任务。
最后,你也可以创建自己的串行队列或并发队列。这就是说,至少有五个队列任你处置:主队列、四个全局调度队列,再加上任何你自己创建的队列。
3.GCD相比其他多线程有哪些优点?
GCD 能通过推迟昂贵计算任务并在后台运行它们来改善你的应用的响应性能。GCD 提供一个易于使用的并发模型而不仅仅只是锁和线程,以帮助我们避开并发陷阱。
GCD 具有在常见模式(例如单例)上用更高性能的原语优化你的代码的潜在能力。
GCD 会自动利用更多的CPU内核(比如双核、四核)
4.GCD术语
串行(Serial):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)并发(Concurrent):可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效。
同步(Synchronous):在当前线程中执行任务,不具备开启新线程的能力
异步(Asynchronous):在新的线程中执行任务,具备开启新线程的能力
5.使用GCD
1.认识主队列,感受串行队列的运行,运行结果打印的是 1,2,3,4,顺序执行。1 2 3 4 5 6 7 8 9 10 11 12 13 | dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_async(mainQueue, ^{ NSLog(@"1"); }); dispatch_async(mainQueue, ^{ NSLog(@"2"); }); dispatch_async(mainQueue, ^{ NSLog(@"3"); }); dispatch_async(mainQueue, ^{ NSLog(@"4"); }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 | dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(defaultQueue, ^{ NSLog(@"1"); }); dispatch_async(defaultQueue, ^{ NSLog(@"2"); }); dispatch_async(defaultQueue, ^{ NSLog(@"3"); }); dispatch_async(defaultQueue, ^{ NSLog(@"4"); }); |
1 2 3 4 5 6 7 8 9 10 | dispatch_queue_t concurrentQueue = dispatch_queue_create("com.bjsxt.concurrentQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^{ NSLog(@"4"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"5"); }); NSLog(@"6"); }); |
1 2 3 4 | static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"onceToken"); }); |
1 2 3 45 | double delayInSeconds = 2.0; dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, mainQueue, ^{ NSLog(@"延时执行的2秒"); }); |
1 2 3 4 5 6 7 8 9 10 11 12 1314 | dispatch_group_t group = dispatch_group_create(); dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_async(group, defaultQueue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"1"); }); dispatch_group_async(group, defaultQueue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"2"); }); dispatch_group_notify(group, defaultQueue, ^{ NSLog(@"3"); }); //等价于 // dispatch_group_enter(group); // dispatch_async(defaultQueue, ^{ // // NSLog(@"1"); // dispatch_group_leave(group); // }); |
在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行.
1 2 3 4 5 6 7 8 9 10 11 12 1314 | dispatch_queue_t queue = dispatch_queue_create("com.bjsxt.barrierExecute", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"1"); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:4]; NSLog(@"2"); }); dispatch_barrier_async(queue, ^{ NSLog(@"3"); [NSThread sleepForTimeInterval:4]; }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"4"); }); |
1 2 3 4 | dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_apply(5, defaultQueue, ^(size_t i) { NSLog(@"%lu",i); }); |
https://github.com/nixzhu/dev-blog
http://objccn.io/issue-2-1/
相关文章推荐
- iOS开发——Scheme白名单
- iOS开发:WebKit、Safari以及SafariViewController
- iOS学习----NSNumber的使用
- IOS学习 NSMutableArray中元素排序
- iOS自定义推送音效
- iOS: 从ipa提取图片资源文件及从iOS设备提取ipa文件的方法
- iOS开发证书变成“此证书的签发者无效”解决方法
- iOS开发--控件
- iOS开发-自定义控件的方式及注意(一)
- iOS闭包循环引用讲解
- iOS开发中如何合理地制造BUG
- iOS开发技巧系列---打造强大的BaseModel
- iOS中创建.gitignore文件
- iOS动画图层 — iOS模糊效果
- ios怎么让图片只有上半边圆角?
- iOS自带的拨号和短信功能
- iOS开发--即时通讯常用第三方库
- iOS8 之后对 SearchController的使用
- iOS国际化(多国语言设置)
- iOS开发之键盘