iOS - GCD(多线程)简单示例:

来源:互联网 发布:下周回国贾跃亭 知乎 编辑:程序博客网 时间:2024/04/23 19:37


1. 在n秒后在新线程里执行某些操作。ps:定时器需要在新线程里执行

double delayInSeconds = 2.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));dispatch_after(popTime, dispatch_get_main_queue(), ^(void){    //coding});


2.在后台执行某些操作:

dispatch_async(dispatch_get_global_queue(0, 0), ^{      // coding });


3.在主线程执行某些操作:ps:有时候在这里面更新UI

dispatch_async(dispatch_get_main_queue(), ^{      // coding });



4.执行某些需要长时间的操作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{      // coding});


GCD中有三种队列类型:
1.The main queue: 与主线程功能相同。实际上,提交至main queue的任务会在主线程中执行。main queue可以调用dispatch_get_main_queue()来获得。因为main queue是与主线程相关的,所以这是一个串行队列。
2.Global queues: 全局队列是并发队列,并由整个进程共享。进程中存在三个全局队列:高、中(默认)、低、后台四个优先级队列。可以调用dispatch_get_global_queue函数传入优先级来访问队列。优先级:

#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
3.用户队列: 用户队列 (GCD并不这样称呼这种队列, 但是没有一个特定的名字来形容这种队列,所以我们称其为用户队列) 是用函数 dispatch_queue_create 创建的队列. 这些队列是串行的。正因为如此,它们可以用来完成同步机制, 有点像传统线程中的mutex。

创建队列
要使用用户队列,我们首先得创建一个。调用函数dispatch_queue_create就行了。函数的第一个参数是一个标签,这纯是为了debug。Apple建议我们使用倒置域名来命名队列,比如“com.dreamingwish.subsystem.task”。这些名字会在崩溃日志中被显示出来,也可以被调试器调用,这在调试中会很有用。第二个参数目前还不支持,传入NULL就行了。
提交 Job
向一个队列提交Job很简单:调用dispatch_async函数,传入一个队列和一个block。队列会在轮到这个block执行时执行这个block的代码。下面的例子是一个在后台执行一个巨长的任务:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{       //coding});
dispatch_async 函数会立即返回, block会在后台异步执行。 
当然,通常,任务完成时简单地NSLog个消息不是个事儿。在典型的Cocoa程序中,你很有可能希望在任务完成时更新界面,这就意味着需要在主线程中执行一些代码。你可以简单地完成这个任务——使用嵌套的dispatch,在外层中执行后台任务,在内层中将任务dispatch到main queue:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        //coding        dispatch_async(dispatch_get_main_queue(), ^{              //coding        });});
还有一个函数叫dispatch_sync,它干的事儿和dispatch_async相同,但是它会等待block中的代码执行完成并返回。结合 __block类型修饰符,可以用来从执行中的block获取一个值。例如,你可能有一段代码在后台执行,而它需要从界面控制层获取一个值。那么你可以使用dispatch_sync简单办到:
__block NSString *stringValue;dispatch_sync(dispatch_get_main_queue(), ^{        // coding});[stringValue autorelease];// use stringValue in the background now
我们还可以使用更好的方法来完成这件事——使用更“异步”的风格。不同于取界面层的值时要阻塞后台线程,你可以使用嵌套的block来中止后台线程,然后从主线程中获取值,然后再将后期处理提交至后台线程:
    dispatch_queue_t bgQueue = myQueue;    dispatch_async(dispatch_get_main_queue(), ^{        NSString *stringValue = [[[textField stringValue] copy] autorelease];        dispatch_async(bgQueue, ^{            // use stringValue in the background now        });    });

取决于你的需求,myQueue可以是用户队列也可以使全局队列。


Ps:dispatch queue是一个轻量级的,不用有太多考虑,随意使用。

0 0
原创粉丝点击