第三章 3.2.2 dispatch_queue_create

第一种获取Dispatch Queue的方法是通过GCD的API"dispatch_queue_create"生成Dispatch Queue。

dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("生成队列的名称", NULL);

第一个参数:
指定生成返回的Dispatch Queue的名称
命名规则:简单易懂
该名称在Xcode和Instruments的调试器中作为Dispatch Queue的名称表示
该名称也会出现在程序崩溃时所生成的CrashLog中

第二个参数:
指定为NULL或DISPATCH_QUEUE_SERIAL,生成Serial Dispatch Queue。
指定为DISPATCH_QUEUE_CONCURRENT,生成Concurrent Dispatch Queue。

返回值:
表示Dispatch Queue的dispatch_queue_t类型

问题一、dispatch_queue_create生成Serial Dispatch Queue的注意事项?
生成多个Serial Dispatch Queue时,各个Serial Dispatch Queue将并行执行,虽然一个Serial Dispatch Queue只能执行一个处理,但如果将多个处理分别追加到同样数量的多个Serial Dispatch Queue中,每个Serial Dispatch Queue执行一个处理,这多个处理其实是并行执行,此时效果将和使用Concurrent Dispatch Queue一样。

问题二、多个Serial Dispatch Queue引发的问题?
一个Serial Dispatch Queue只能生成一个线程,过多的使用Serial Dispatch Queue会消耗大量内存,降低系统响应性能。

问题三、Serial Dispatch Queue的用途?
避免多线程编程的问题之一———多个线程更新相同资源导致的数据竞争问题,可以使用Serial Dispatch Queue解决。

不用考虑数据竞争,可以并行执行时,可以使用Concurrent Dispatch Queue,Concurrent Dispatch Queue由XNU管理线程,不会发生Serial Dispatch Queue引发的问题。

问题四、Dispatch Queue的内存管理?
因为Dispatch Queue没有像Block那样具有作为OC对象处理的技术,所以生成的Dispatch Queue必须由程序员负责释放。

dispatch_release(mySerialDispatchQueue);

使用dispatch_release()函数释放生成的Dispatch Queue

相应地也存在dispatch_retain()函数

dispatch_retain(mySerialDispatchQueue);

例子:
dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.exemple.gcd.MyConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(myConcurrentDispatchQueue, ^{
        NSLog(@"block on myConcurrentDispatchQueue");
});
    
dispatch_release(myConcurrentDispatchQueue);

问题五、上面的例子代码,立即释放myConcurrentDispatchQueue是否有问题?
完全没有问题。
例子代码中,myConcurrentDispatchQueue持有对dispatch_queue_create()函数生成对象,而在dispatch_async函数中追加Block到生成的Dispatch Queue中,所以Block通过dispatch_retain函数也持有生成的Dispatch Queue,虽然dispatch_release立即释放myConcurrentDispatchQueue对生成Dispatch Queue的持有,但Block还持有,只有Block执行结束后才会释放Dispatch Queue,Dispatch Queue才会被废弃。
(上面所说的Block通过dispatch_retain函数持有Dispatch Queue,应该涉及到底层实现)

总结:
在通过函数或其他方法获取Dispatch Queue以及其他名称中含有create的API生成的对象时,有必要通过dispatch_retain函数持有,在不需要时通过dispatch_release函数释放。

你可能感兴趣的:(第三章 3.2.2 dispatch_queue_create)