iOS GCD隊列dispatch簡單的使用

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個條件調試

  1. 使用的是異步任務,使用的是dispatch中的async系列函數

  2. 隊列必須是異步的

   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]);
         });
相關文章
相關標籤/搜索