谈谈关于GCD相关问题
来源:互联网 发布:基于协同过滤算法 编辑:程序博客网 时间:2024/05/14 08:09
记录下关于学习和使用GCD的一些问题和理解。
GCD,Grand Central Dispatch的简称。首次发布在Mac OS X 10.6 ,iOS 4开始引入使用,是以纯C为底层的强大技术。其操作机制是基于线程上队列对于任务的调度执行,遵循FIFO(First In First Out)。
对于线程常用的三个方式的比较:
NSThead主要做简单的,缺点是无法管理线程的数量,需要手动管理线程。
// 开启并且执行一个线程+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;// 创建一个线程但是不会执行,需要手动调用- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument // 通过通知中心监听此消息达到监听线程结束的目的NSThreadWillExitNotification
NSOperation是基于OC的面向对象的多线程可以管理线程数,比GCD多了一些简单实用的功能。
// maxConcurrentOperationCount设置最大开启的线程数,设置为1,则成为串行队列,否则,为并发队列
GCD是基于C的,效率高,会自动的管理线程周期(包括创建线程,任务处理,销毁线程)。
注意一个技巧:三种线程方式,都可以使用[NSThread currentThread]追踪任务所在的线程。
下面我们主要看下GCD的核心三个方面:线程、 队列 、任务(block执行块)。原理是将一段(Block)代码作为特定任务,放到指定的队列(queue:Serial(串行,同时只能执行一个任务)/globel(并行,同时可执行多个任务,但执行顺序是随机的)/main(全局的Serial,在主线程里面执行任务) dispatch queue)里,进行同步/异步(dispatch_sync/dispatch_async)处理。根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。其中 线程分为:主线程、分线程(子线程)
队列分为:
(1)串行队列:自己手动创建的,队列中的任务只会顺序执行 (类似排队)(DISPATCH_QUEUE_SERIAL也可使用NULL代替)。
dispatch_queue_t q = dispatch_queue_create(“....”, DISPATCH_QUEUE_SERIAL);
(2)并行队列:自己手动创建的,队列中的任务通常会并发执行(类似赛跑)
dispatch_queue_t q = dispatch_queue_create("......", DISPATCH_QUEUE_CONCURRENT);
( 3)系统提供的几个并发队列。他们叫做全局调度队列(Global Dispatch Queues) ,一般进程中存在三个全局队列。全局队列有着依次从低到高的四个不同优先级:background、low、default 以及 high。PS:Apple 的 API 也会使用这些队列,所以你添加的任何任务都不会是这些队列中唯一的任务。
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
(4) 主队列,提交至main queue的任务会在主线程中执行,是一个默认的串行队列。
dispatch_queue_t q = dispatch_get_main_queue();
处理线程中的队列任务,我们需要记得两句话:同步异步(dispatch_sync/dispatch_async)决定开不开线程,串行并行决定开几条线程。
关于我们在实际开发中,利用GCD去做一些线程处理时,常用方法有下面几种简单的使用:
// 异步执行:dispatch_async(dispatch_get_global_queue(0, 0), ^{// something});// 主线程执行:dispatch_async(dispatch_get_main_queue(), ^{// something});// 一次性执行:static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{// code to be executed once});// 延迟2秒执行:double delayInSeconds = 2.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);dispatch_after(popTime, dispatch_get_main_queue(), ^(void){// code to be executed on the main queue after delay});// 自定义dispatch_queue_tdispatch_queue_t urls_queue = dispatch_queue_create("blog.LL86.com", NULL);dispatch_async(urls_queue, ^{ // your code });dispatch_release(urls_queue);// 快速迭代遍历dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){ // 执行10次代码,index顺序不确定});//常用结构dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 耗时的操作 dispatch_async(dispatch_get_main_queue(), ^{ // 主线程刷新UI }); }); 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(), ^{ // 等前面的异步操作都执行完毕后,回到主线程...});其中需要注意的是:
dispatch_after 是 延迟提交任务,并不是延迟多少秒后立即执行。在使用GCD做定时源时,使用dispatch_source_create创建一个定时器并绑定到主分派队列上。GCD定时器是基于分派队列,而不是像NSTimer那样基于运行循环,这意味着把他们用在多线程应用中要容易的多。
dispatch_suspend(queue) 挂起队列,并不是立即暂停正在运行的block任务,而是在当前block任务执行结束以后,暂停后续的block运行。\-。-/~
dispatch_sync 都不陌生的是,这句代码本身就是要放入主线程中运行的,因此有时不注意的一些操作会常造成我们常说的死锁现象(也就是线程相互等待现象)。
- 谈谈关于GCD相关问题
- iOS中GCD的相关问题
- gcd相关
- GCD相关
- 谈谈关于统一通信的问题
- 关于yum相关问题
- 关于ad10相关问题
- 关于GCD的一些介绍及相关使用
- 谈谈MVC项目中的缓存功能设计的相关问题
- 关于GCD
- 关于GCD
- 关于GCD
- 关于GCD
- 关于gcd
- 关于gcd
- 关于 数据库的 相关问题
- 关于字符串的相关问题
- 关于shell的相关问题
- C++栈和队列
- iOS_时间戳与日期转换(几分钟前)
- 更改ORACLE所占用的8080端口号
- 一个好用的在线正则网站
- Ajax提高篇(6)服务器端脚本和程序中用 JSON 进行响应和回复
- 谈谈关于GCD相关问题
- poj1305毕达哥拉斯三元组
- ARC下内存管理问题
- android.content.res.Resources$NotFoundException: Unable to find resource ID #0xffffffff
- Linux设备驱动模型的private_data 简单理解
- 苹果审核reject理由大全(12):qq、微信的登录、分享等功能
- Ajax提高篇(7)Ajax实现简单的下拉框联动显示数据
- char (*)[]无法传给参数char **
- 为什么程序员有高薪却不高兴?