如果在本文之前要了解一下线程的基本知识,请访问下面的网址:http://www.cnblogs.com/alunchen/p/5337608.html
1.简介
GCD不仅适用于Object-C,也适用于C、C++
GCD在C接口中添加了一些优秀的概念,比如工作单元、无痛后台处理(painless background processing)、自动线程管理,他们可在所有基于C的语言中使用。
GCD的重要一个概念是队列,可以保证始终在主线程上执行工作的队列,非常适合非线程安全的UIKit。也可以自己创建队列。
GCD队列遵循FIFO(先进先出)原则。
2.使用之前-block
在使用GCD之前,一定要理解新语法block的使用,对于尽量充分利用GCD非常重要。block可替代object-c中的委托模式或C中的回调函数。这里不详细介绍block了,请参照下面文章 http://www.cnblogs.com/alunchen/p/5341057.html
3.开启新线程与主线程
下面我们用GCD开启一个新线程。注意的是当我们执行下面的方法,当执行完doSomething(),其实startTime已经释放了,但是注意的block一个关键点是,如果一个程序块block在执行过程中访问任何的‘外部’变量,那么该程序块block被创建时会进行一些特殊的设置工作,以允许程序块访问这些变量。所以,其实在调用dispatch_async时,startTime被retain了一次,而且程序块block内部赋给了一个内部同名startTime的新的不可变的变量。
-(void) doSomething() { NSDate *startTime = [NSDate date]; //取得一个全局队列,优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //开启异步线程 dispatch_async(queue, ^{ //在这里做一些任何耗时的处理 NSDate *endTime = [NSDate date]; NSLog(@"完成时间:%f", [endTime timeIntervalSinceDate: startTime]); }); }
上面创建了一个异步线程,但是我们想要在异步线程中做任何更新等UI操作是不可能的,下面例子是执行完线程后,获取主线程做UI操作:
-(void) doSomething() { NSDate *startTime = [NSDate date]; //取得一个全局队列,优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //开启异步线程 dispatch_async(queue, ^{ //在这里做一些任何耗时的处理 //得到主线程,做UI操作 dispatch_async(dispatch_get_main_queue(), ^{ //在这里做一些更新UI等UI操作 }); }); }
4.并发程序块-dispatch group(提高执行速度)
如果在新开启的异步线程A中,运行需要的时间大概需要10秒,那么我们想象一下,这个运行时间会不会太长。现在,IOS提供了一个dispatch group分派组给我们快速的执行。原理是将一个组的上下文中通过dispatch_group_async()函数异步分派的所有程序块同时运行,那就不需要10秒那么长的时间了。也可以使用dispatch_group_notify()指定一个额外的程序块,让它在组中的所有程序块运行完成时再执行。可看下面例子:
//上面的doSomething()需要10秒,这里的少于10秒 -(void) doSomething() { NSDate *startTime = [NSDate date]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //开启异步线程 dispatch_async(queue, ^{ //在这里做一些任何耗时的处理 doSomething2(); //这里开始定义group dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ //这里这一些其他的耗时处理 doSomething3(); }); //等待上面所有的线程运行完,这里才执行(notify的作用) dispatch_group_notify(group, queue, ^{ dispatch_async(dispatch_get_main_queue(), ^{ //做一些主线程更新UI的操作 doSomethingWithUI(); }); }); }); }