Objective C 高级进阶— GCD队列浅析(一)

来源:互联网 发布:杭州淘宝拍摄地点中山 编辑:程序博客网 时间:2024/05/16 15:16

前边已经介绍了GCD的基本概念,下边来介绍一下GCD队列的基本用法,以及一些其他注意的地方。

本文参考链接:https://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

一:队列的几种类型:

GCD offers three kinds of queues:Main: tasks execute serially on your application’s main thread(主队列,在你程序的主线程中顺序执行)Concurrent: tasks are dequeued in FIFO order, but run concurrently and can finish in any order.(并行队列,任务遵循先入先出,但同时执行并按照任意顺序完成,完成顺序取决于任务的复杂度)Serial: tasks execute one at a time in FIFO order(串行队列,依次执行,遵循先入先出)


二:向主队列注册block函数

The main queue is automatically created by the system and associated with your application’s main thread. 
Your application uses one (and only one) of the following three approaches to invoke blocks submitted to the main queue:Calling dispatch_mainCalling UIApplicationMain (iOS) or NSApplicationMain (OS X)Using a CFRunLoopRef on the main thread


详解: 主队列是由系统自动创建的并且与你应用的主线程相结合,你的应用只能用下边的一种方式来把block函数注册到你的主队列中。到这里大家可能不太理解者到底怎么用呢,下边来看实例代码
@autoreleasepool {        return UIApplicationMain(argc, argv,nil,NSStringFromClass([AppDelegateclass]));    }

注意,这里是用到的就是UIApplicationMain方式,对于iOS要用这种方式

Important: GCD is a C level API; it does not catch exceptions generated by higher level languages. Your application must catch all exceptions before returning from a block submitted to a dispatch queue.

注意:GCD的接口是基于C的,它并不能捕捉到有高级别语言产生的exceptions, 你的应用必须在执行把block函数提交到队列之前捕捉所有的异常。

三. 队列使用的相关代码
创建一个队列
dispatch_queue_t myQueue = dispatch_queue_create("com.openJailBreak.ios", NULL)
此处要注意的是,第一个参数是一个identifier,用于表示一个队列,关键的是第二个参数,先来看官方原文:
attrIn OS X v10.7 and later, specify DISPATCH_QUEUE_SERIAL (or NULL) to create a serial queue or specify DISPATCH_QUEUE_CONCURRENT to create a concurrent queue. In earlier versions of OS X, you must specify NULL for this parameter.
意思是,如果第二个参数设置为DISPATCH_QUEUE_SERIAL或者NULL,意味着创建了一个串行队列,如果指定一个DISPATCH_QUEUE_CONCURRENT意味着创建了一个并行队列。在早期的版本中并行队列是不可用的,需要设置为NULL,从OS X10.7,iOS 4.3以后才可用,先来看一下官方接口文档:
/*! * @const DISPATCH_QUEUE_SERIAL * @discussion A dispatch queue that invokes blocks serially in FIFO order. */#define DISPATCH_QUEUE_SERIAL NULL/*! * @const DISPATCH_QUEUE_CONCURRENT * @discussion A dispatch queue that may invoke blocks concurrently and supports * barrier blocks submitted with the dispatch barrier API. */#define DISPATCH_QUEUE_CONCURRENT \DISPATCH_GLOBAL_OBJECT(dispatch_queue_attr_t, \_dispatch_queue_attr_concurrent)__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3)DISPATCH_EXPORT

好了,到这里我们就该清楚了,现在来用三种方式来创建一个队列
dispatch_queue_t queue_t_concurrent = dispatch_queue_create("com.openJailBreak.concurrent", DISPATCH_QUEUE_CONCURRENT);//concurrentdispatch_queue_t queue_t_serial = dispatch_queue_create("com.openJailBreak.serial", DISPATCH_QUEUE_SERIAL);//serialdispatch_queue_t queue_t_null = dispatch_queue_create("com.openJailBreak.null", NULL); //serilal

下边进入讨论议题,来看原文:
Discussion

Blocks submitted to a serial queue are executed one at a time in FIFO order. Note, however, that blocks submitted to independent queues may be executed concurrently with respect to each other. Blocks submitted to a concurrent queue are dequeued in FIFO order but may run concurrently if resources are available to do so.

When your application no longer needs the dispatch queue, it should release it with the dispatch_release function. Any pending blocks submitted to a queue hold a reference to that queue, so the queue is not deallocated until all pending blocks have completed.


相信大家都能理解这里的重点,此处还是要强调一下:

只有提交到串行队列的block函数出队列时才会FIFO,而对于独立的队列可能会并行执行。提交到并行队列的block出队时也是FIFO,但是在执行的过程中可能会根据系统的资源来并行执行。

当你的应用不在需要队列时,可以使用dispatch_release来释放,但如果队列中又任何pending状态的block,此时是无法dealloc的直到pending block完成。


好了,第一部分就先讲到这里吧,后续会继续发布,感谢大家!


原创粉丝点击