分享

GCD dispatch queue的使用

 UchihaItachiF 2015-12-05

dispatch queue概述

dispatch queue的优势:与对应的线程代码相比,更加易用; 执行任务时,效率更高。

为dispatch queue定义任务时,只能使用函数块对象

所有的dispatch queue都是先进先出的数据结构(到底它还是queue~),因此,添加到dispatch queue中的任务也是按添加的顺序开始执行的。

dispatch queue分类:

类型 描述
Serial 又称private dispatch queues,每个时刻只执行一个任务。Serial queue通常用于同步访问特定的资源。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。
Concurrent 又称global dispatch queue,可以并发地执行多个任务。你只能使用系统提供的4种global dispatch queue,不能自己创建。(iOS 5.0之前是3种)。
Main dispatch queue 它是全局可用的serial queue,它是在应用程序主线程上执行任务的。

 

关于dispatch queue,需要牢记以下几个关键点:

  1. 不同的dispatch queue之间是并发执行的。序列化的任务,只被限制在单独的Serial queue中。
  2. 系统决定同时执行的任务数量。
  3. 新任务开始时,系统会考虑dispatch queue的优先级。
  4. 当任务添加到dispatch queue中时,任务必须准备好随时执行。
  5. 私有的dispatch queue是引用计数的对象。

创建及管理dispatch queue

获取global dispatch queue

使用dispatch_get_global_queue函数,其第一个参数指定dispatch queue的优先级,取值可以是DISPATCH_QUEUE_PRIORITY_HIGHTDISPATCH_QUEUE_PRIORITY_DEFAULTDISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_BACKGROUND(iOS 5.0加入的); 第二个参数,目前只能为0或NULL。

创建serial dispatch queue

使用dispatch_queue_create函数,第一个参数指定其名称,第二个参数指定其属性,属性是保留给苹果未来用的,当前,应该指定其为NULL。

dispatch queue的内存管理

使用dispatch_retain及dispatch_release函数。不应该保留或释放main dispatch queue以及任何global dispatch queue。

为dispatch queue提供自定义上下文信息

使用dispatch_set_context及dispatch_set_context函数。

为dispatch queue提供清理函数

可以使用dispatch_set_finalizer_f函数为dispatch queue设置清理函数,当dispatch queue的引用计数达到0时,其所指定的清理函数就会被调用。

为dispatch queue添加任务

向一个queue中添加一个单独的任务

可以以同步或异步的方式进行添加。四个函数:dispatch_async、dispatch_async_f、dispatch_sync、dispatch_sync_f。千万不要使用dispatch_sync或dispatch_sync_f将同一个dispatch queue中正在执行的任务再次添加到这个queue中,如果这样做,会导致死锁。

并发执行循环迭代

使用dispatch_apply或dispatch_apply_f函数。 如果你要使用这两个函数执行类似

1 for (int i = 0; i < 10; i++) {
2     printf("loop-----%i\n", i);
3 }

的任务,可以使用

1 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2 dispatch_apply(10, queue, ^(size_t i) {
3     printf("loop-----%zd\n", i);
4 });

1 void loopwork(void *p, size_t i) {
2     printf("loop-----%zd\n", i);
3 }
4 
5 - (void)viewDidLoad {
6     [super viewDidLoad];
7     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
8     dispatch_apply_f(10, queue, NULL, loopwork);
9 }

挂起或唤醒dispatch queue

dispatch_suspend会挂起dispatch queue,但并不意味着当前正在执行的任务会停下来,这只会导致不再继续执行还未执行的任务。dispatch_resume会唤醒已挂起的dispatch queue。你必须确保它们成对调用。

 

苹果公司敬告:Migrating Away from Threads。远离NSThread~。执行多线程任务时,要么使用operation queue,要么使用dispatch queue。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多