iOS從iOS 4引入了libdispatch來實現消息隊列的編程java
1、dispatch隊列的生成能夠有這幾種方式編程
1. dispatch_queue_t queue = dispatch_queue_create("user.dispatch.mulitworker", DISPATCH_QUEUE_SERIAL); //生成一個串行隊列,隊列中的block按照先進先出(FIFO)的順序去執行,實際上爲單線程執行。第一個參數是隊列的名稱,在調試程序時會很是有用,全部儘可能不要重名了。併發
2. dispatch_queue_t queue = dispatch_queue_create("com.dispatch.concurrent", DISPATCH_QUEUE_CONCURRENT); //生成一個併發執行隊列,block被分發到多個線程去執行異步
3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //得到程序進程缺省產生的併發隊列,可設定優先級來選擇高、中、低三個優先級隊列。因爲是系統默認生成的,因此沒法調用dispatch_resume()和dispatch_suspend()來控制執行繼續或中斷,另外其具備串行隊列的特性。async
須要注意的是,三個隊列不表明三個線程,可能會有更多的線程。併發隊列能夠根據實際狀況來自動產生合理的線程數,也可理解爲dispatch隊列實現了一個線程池的管理,對於程序邏輯是透明的。函數
官網文檔解釋說共有三個併發隊列,但實際還有一個更低優先級的隊列,設置優先級爲DISPATCH_QUEUE_PRIORITY_BACKGROUND。Xcode調試時能夠觀察到正在使用的各個dispatch隊列。優化
4. dispatch_queue_t queue = dispatch_get_main_queue(); //得到主線程的dispatch隊列,實際是一個串行隊列。一樣沒法控制主線程dispatch隊列的執行繼續或中斷。spa
隊列的使用方式線程
//異步執行block,函數當即返回 dispatch_async(queue, ^{ //block具體代碼 }); //同步執行block,函數不返回,一直等到block執行完畢。編譯器會根據實際狀況優化代碼,因此有時候你會發現block其實還在當前線程上執行,並沒用產生新線程。 dispatch_sync(queue, ^{ //block具體代碼 });
可是,這裏咱們須要注意,構成異步隊列必須知足2個條件調試
使用的是異步任務,使用的是dispatch中的async系列函數
隊列必須是異步的
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 耗時的操做 NSLog(@"dispatch_async_global,%d",[[NSThread currentThread] isMainThread]); dispatch_async(dispatch_get_main_queue(), ^{ //注意,這裏不能使用dispatch_sync,不然形成死鎖。 NSLog(@"dispatch_async_main,%d",[[NSThread currentThread] isMainThread]); }); });
關於死鎖,請參考http://www.jianshu.com/p/44369c02b62a
死鎖緣由:首先要明確,dispatch_async和dipatch_sync都是入隊操做,其中dispatch_async執行完後把block拋擲到隊列,而dispatch_sync是等待主隊列執行完以後再入隊操做,可是主隊列須要等待dispatch_sync執行才執行任務,所以形成互相等待問題,從而形成死鎖。
關於併發隊列
dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("user.group.mulitworker", DISPATCH_QUEUE_CONCURRENT); //注意,必須指定隊列類型 dispatch_group_async(group, queue, ^{ NSLog(@"1,%d",[[NSThread currentThread] isMainThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"2,%d",[[NSThread currentThread] isMainThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"3,%d",[[NSThread currentThread] isMainThread]); }); dispatch_notify(group, queue, ^{ NSLog(@"finish,%d",[[NSThread currentThread] isMainThread]); //異步執行 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"main,%d",[[NSThread currentThread] isMainThread]); //主線程執行 }); });
串行分組隊列
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, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"group1"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"group2"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"group3"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //主線程執行 NSLog(@"updateUi,%d",[[NSThread currentThread] isMainThread]); });
關於
dispatch_notify和dispatch_group_notify二者都用於觀察group,可是前者是異步的,後者是同步的
延時隊列
dispatch_queue_t queue= dispatch_get_main_queue(); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), queue, ^{ NSLog(@"主隊列--延遲執行------%@",[NSThread currentThread]); });