关于Main Dispatch Queue和Global Dispatch Queue。
上一篇说了创建Dispatch Queue的方法,其实不用dispatch_queue_create函数也可以获取Dispatch Queue,那就是Main Dispatch Queue 和 Global Dispatch Queue。
顾名思义,Main Dispatch Queue是在主线程中执行的Dispatch Queue,主线程只能有一个,所以Main Dispatch Queue是一个串行的Dispatch Queue,即Serial Dispatch Queue。
所有追加到Main Dispatch Queue中的处理都是在RunLoop中执行。由于是在主线程中执行,所以要将用户界面的更新等一些必须在主线程中执行的处理追加到Main Dispatch Queue中使用。这和NSObject类的performSelectorOnMainThread实例方法相似。
Global Dispatch Queue是Concurrent Dispatch Queue。没有必要用dispatch_queue_create函数逐个生成Concurrent Dispatch Queue,只要获取Global Dispatch Queue就可以了。Global Dispatch Queue有四个执行优先级,分别是高优先级(High Priority)、默认优先级(Default Priority)、低优先级(Low Priority)和后台优先级(Background Priority)。
获取Main Dispatch Queue的方法如下:
/** * 获取Main Dispatch Queue */ - (void)getMainDispatchQueue { dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_async(mainQueue, ^{ NSLog(@"%@: mainQueue is main thread:%i", [NSThread currentThread], [NSThread isMainThread]); }); }
输出结果:
2015-06-16 20:51:48.710 GCD_Study[19270:607] {name = (null), num = 1}: mainQueue is main thread:1
dispatch_get_main_queue函数就是获取Main Dispatch Queue的方法。另外,切记往Main Dispatch Queue中追加任务要用dispatch_async函数,因为dispatch_sync函数在追加任务时,在指定的任务执行结束前该函数是不会返回的,所以如果用dispatch_sync函数往Main Dispatch Queue中追加任务,会导致程序死锁。
dispatch_get_main_queue函数的定义如下:
/*! * @function dispatch_get_main_queue * * @abstract * Returns the default queue that is bound to the main thread. * * @discussion * In order to invoke blocks submitted to the main queue, the application must * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main * thread. * * @result * Returns the main queue. This queue is created automatically on behalf of * the main thread before main() is called. */ __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) DISPATCH_EXPORT struct dispatch_queue_s _dispatch_main_q; #define dispatch_get_main_queue() DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q)
获取Global Dispatch Queue的方法如下:
/** * 获取四个优先级的Global Dispatch Queue */ - (void) getGlobalDispatchQueue { //高优先级 DISPATCH_QUEUE_PRIORITY_HIGH dispatch_queue_t highPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); //默认优先级 DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_queue_t defaultPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //低优先级 DISPATCH_QUEUE_PRIORITY_LOW dispatch_queue_t lowPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); //后台优先级 DISPATCH_QUEUE_PRIORITY_BACKGROUND dispatch_queue_t backgroundPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); }
dispatch_get_global_queue需要传递两个参数,第一个是指定获得的优先级,第二个是一个flogs值,源码中是这样定义的:
/*! * @function dispatch_get_global_queue * * @abstract * Returns a well-known global concurrent queue of a given priority level. * * @discussion * The well-known global concurrent queues may not be modified. Calls to * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will * have no effect when used with queues returned by this function. * * @param priority * A priority defined in dispatch_queue_priority_t * * @param flags * Reserved for future use. Passing any value other than zero may result in * a NULL return value. * * @result * Returns the requested global queue. */ __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);
flags是保留着以后用的,现在只能传0,传任何大于零的值只能返回一个NULL。
另外,对于Main Dispatch Queue和Global Dispatch Queue执行dispatch_retain或者dispatch_release是不会引起变化的,也不会有任何问题。