cocoa_chen

GCD编程的简单用法

2014-10-24

什么是GCD

Grand Central Dispatch(GCD)是苹果在OS X Snow Leopard和IOS4后引入的新的多线程编程功能,配合Block可以很简洁高效的处理多线程编程。

GCD应用示例

  • Dispatch Queue
  • dispatch_after函数
  • dispatch_once函数
  • Dispatch Group

1.Dispatch Queue的应用示例如下:

1
2
3
4
dispatch_async (queue,^{
//要执行的代码

});

可以通过dispatch_queue_create函数创建自定义的queue,示例如下:

1
2
3
4
5
dispatch_queue_t myQueue = dispatch_queue_create("com.cocoaChen.gcd.myQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
//要执行的代码

});

通过获取系统提供的Dispatch Queue,可以很方便的在主线程或者后台线程中以后延迟执行Block操作。示例如下:

1
2
3
4
5
6
7
8
9
10
//获取主线程Queue
dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();
//获取高优先级的Global Queue
dispatch_queue_t globalQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
//获取默认优先级的Global Queue
dispatch_queue_t globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//获取低优先级的Global Queue
dispatch_queue_t globalQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
//获取后台优先级的Global Queue
dispatch_queue_t globalQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

将主线程Queue和Global Queue组合使用的例子如下所示:

1
2
3
4
5
6
7
8
9
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//后台处理的耗时操作

//操作完成后在主线程更新UI
dispatch_async(dispatch_get_main_queue(), ^{
//主线程进行的操作

});
});

2.dispatch_after函数

有时候我们需要几秒后执行一个操作处理,这时可以使用dispatch_after函数来实现。示例如下:

1
2
3
4
5
double delayInSeconds = 2.0;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//延时处理的操作

});

3.dispatch_once函数

在生成单例模式时我们需要保证该单例只初始化一次,这时可以通过dispatch_once函数来实现。如下所示:

1
2
3
4
5
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//初始化操作

});

4.Dispatch Group

如果想在追加到Dispatch Queue中的多个处理全部结束后再执行结束的处理,可以使用dispatch_group,dispatch_group_async和dispatch_group_notify来实现,如下所示:

1
2
3
4
5
6
7
8
9
10
11
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
//操作1
});
dispatch_group_async(group, queue, ^{
//操作2
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//全部操作都结束之后的处理操作
});

备注:因为向Queue中追加的处理时,多个线程会并行执行,所以追加处理的执行顺序是不确定的,执行的时候也会发生变化,但是notify中的操作一定是最后执行的。

当在遇到需要某个操作不能与其他操作并行执行的时候,譬如读写操作时,使用dispatch_barrier_async函数可以很方便的解决问题,代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
dispatch_queue_t queue = dispatch_queue_create("com.cocoaChen.barrierQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
//读取操作1
});
dispatch_async(queue, ^{
//读取操作2
});
dispatch_barrier_async(queue, ^{
//写入操作
});
dispatch_async(queue, ^{
//读取操作3
});

这样就可以保证在dispatch_barrier_async中的操作执行时,其他读取的操作不会并行执行(只会进行写入操作),当dispatch_barrier_async中的操作结束之后才会去执行其他的读取操作,起到了安全地读取文件和写入文件的功能,避免了数据竞争。

小结

GCD很大程度上简化了多线程编程,代码也闲的更简洁,使得开发者只需要专注于想处理的任务即可,所以开发者还是尽早熟练的使用GCD把!

Tags: iOS
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章