你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> iOS GCD

iOS GCD

編輯:關於IOS

一、GCD是異步執行任務的技術之一,一般將應用程序中記敘的線程管理用的代碼在系統級中是實現。

開發者只需要定義想要執行的任務並追加到適當的Dispatch Queue中,GCD就能生成必要的線程並計劃執行任務。

 

二、多線程編程

由於使用多線程的程序可以在某個線程和其他線程之間反復多次進行上下文切換,因此看上去就好像一個CPU核能夠並行的執行多個線程一樣,而且在具有多個CPU核的情況下,就不是“看上去像”了,而是真的提供了多個CPU核並行執行任務的多個線程的技術。

多線程編程容易發生各種編程問題:比如多個線程更新相同的資源會導致數據的不一致(數據競爭)、停止等待事件的線程會導致多個線程相互持續等待(死鎖)、使用太多線程會消耗大量的內存資源等等。

盡管會有問題,但是為什麼還要用呢?

在應用程序啟動時,通過最先執行的線程,即主線程來描繪用戶界面、處理用戶觸摸事件等,但是如果在該主線程中進行長時間的處理,就會妨礙主線程中被稱為RunLoop的主循環的執行,從而導致不能跟新用戶界面,應用程序的畫面長時間停滯等問題。

 

三、GCD 的 API

1.Dispatch Queue

開發者要做的只是定義想要執行的任務並追加到適當的DispatchQueue中。

在Block中定義想要執行的任務,然後追加到Dispatch Queue中

Dispatch Queue是執行處理的等待隊列,通過dispatch_async等API,在Block語法中記敘想要執行的處理並將其追加到Dispatch Queue中,Dispatch Queue按照追加的順序(FIFO)執行處理。

另外,在執行處理時存在兩種Dispatch Queue:

Dispatch Queue的種類
 說明
 
Serial Dispatch Queue
 等待現在執行中處理結束
 
Concurrent Dispatch Queue
 不等待現在執行中處理結束
 

解釋說明一下:

(1)         Serial Dispatch Queue:就是要等待現在執行中處理結束後才可以進行下一個任務的執行處理,假如現在有blk1,blk2,blk3,在Serial Dispatch Queue中,那麼同時執行處理數只能是一個,而且按按添加順序FIFO進行處理,即先執行blk1,執行結束後再執行blk2,執行結束再進行blk3的執行。

(2)         Concurrent Dispatch Queue:就是一個線程的執行不等待現在(當前)執行中的任務處理結束就可以開始另一個任務的執行處理。同樣假如有blk1,blk2,blk3在Concurrent Dispatch Queue中,那麼首先執行blk1,不管blk1是否執行處理結束,都開始執行後面的blk2,不管blk2是否執行結束,都開始執行後面的blk2。

這樣雖然不用等待處理結束,可以並行執行多個任務處理,但是並行處理數取決於當前系統的狀態,有它決定Concurrent Dispatch Queue中並行執行的處理數。所謂並行執行就是使用多個線程來同時執行多個處理任務(block中的執行任務)。

 

SerialDispatchQueue同時只能執行一個追加處理

ConcurrentDispatchQueue並行執行多個追加處理

雖然SerialDispatchQueue ConcurrentDispatchQueue受到系統資源的限制,但是用dispatch_queue_create可以生成任意多個Dispatch Queue

 當生成多個SerialDispatchQueue時,各個SerialDispatchQueue將並行執行,雖然一個SerialDispatchQueue同時只能執行一個追加處理,但是如果將處理分別追加到4個

Serial Dispatch Queue中,各個Serial Dispatch Queue執行一個,即為同時執行4個處理

但是生成Serial Dispatch Queue的個數受系統限制

   

為了避免多線程編程的問題之一---數據競爭,就可以使用Serial Dispatch Queue。

當想並行執行且不發生數據競爭等問題時就應該使用Concurrent Dispatch Queue。

[cpp]
//以下代碼是兩種生成Serial Dispatch Queue的方式  
    dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("cn.edu.scnu.mySerialDispatchQueue", NULL); 
    //        dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("cn.edu.scnu.mySerialDispatchQueue", DISPATCH_QUEUE_SERIAL); 

//以下代碼是兩種生成Serial Dispatch Queue的方式
    dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("cn.edu.scnu.mySerialDispatchQueue", NULL);
    //        dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("cn.edu.scnu.mySerialDispatchQueue", DISPATCH_QUEUE_SERIAL);

dispatch_queue_create,該方法中的第一個參數指定SerialDispatchQueue的名稱,DispatchQueue的名稱推薦使用應用程序ID之中逆序全程域名,第二個參數指定為NULL(或者DISPATCH_QUEUE_SERIAL)時即表示生成的是Serial Dispatch Queue,指定為DISPATCH_QUEUE_CONCURRENT時即表示生成的是Concurrent Dispatch Queue

 

[cpp]
//以下代碼生成ConcurrentDispatchQueue  
    dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("cn.edu.scnu.myConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT); 
 
    dispatch_async(myConcurrentDispatchQueue, ^{ 
        NSLog(@"block on my ConcurrentDispatchQueue"); 
    }); 

//以下代碼生成ConcurrentDispatchQueue
    dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("cn.edu.scnu.myConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);

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

2、MainDispatch Queue 和 Global Dispatch Queue

實際上不用特意生成DispatchQueue,系統也會提供幾個給我們,就是Main DispatchQueue 和 Global Dispatch Queue

 Main Dispatch Queue就是主線程中執行的Dispatch Queue,因為主線程只有一個,所以Main DispatchQueue自然就是 Serial Dispatch Queue

[cpp]
//獲取Main Dispatch Queue  
    dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue(); 

//獲取Main Dispatch Queue
    dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();

GlobalDispatch Queue是所有應用程序都能夠使用的Concurrent Dispatch Queue,沒有必要通過dispatch_queue_create方法逐個生成Concurrent Dispatch Queue,只要獲

取GlobalDispatch Queue使用即可。

 Global Dispatch Queue有四個優先級:High Priority,Default Priority,Low Priority,Background Priority

 

[cpp]
//獲取高優先級的的Global Dispatch Queue  
   /*
    DISPATCH_QUEUE_PRIORITY_HIGH       
    DISPATCH_QUEUE_PRIORITY_DEFAULT    
    DISPATCH_QUEUE_PRIORITY_LOW        
    DISPATCH_QUEUE_PRIORITY_BACKGROUND
    */ 
   dispatch_queue_t globalDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
   //第一個參數指定Global Dispatch Queue的優先級,第二個參數指定為0 

 //獲取高優先級的的Global Dispatch Queue
    /*
     DISPATCH_QUEUE_PRIORITY_HIGH      
     DISPATCH_QUEUE_PRIORITY_DEFAULT   
     DISPATCH_QUEUE_PRIORITY_LOW       
     DISPATCH_QUEUE_PRIORITY_BACKGROUND
     */
    dispatch_queue_t globalDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    //第一個參數指定Global Dispatch Queue的優先級,第二個參數指定為0

 

3、dispatch_set_target_queue

dispatch_queue_create函數生成的Dispatch Queue不管是Serial Dispatch Queue還是Concurrent Dispatch Queue,都是使用與默認優先級的Global Dispatch Queue相同執

行優先級的線程

如果想變更生成的Dispatch Queue的執行優先級要使用dispatch_set_target_queue方法。

[cpp]
dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("cn.edu.scnu.mySerialDispatchQueue", NULL); 
    dispatch_queue_t globalDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
    dispatch_set_target_queue(mySerialDispatchQueue, globalDispatchQueue); 
    //指定要變更執行優先級的dispatch queue為dispatch_set_target_queue方法的第一個參數,指定與要使用的執行優先級相同優先級的Global Dispatch Queue為第二個參數(目標)  
    //第一個參數不可以指定為系統提供的Main Dispatch Queue 和 Global Dispatch Queue 

dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("cn.edu.scnu.mySerialDispatchQueue", NULL);
    dispatch_queue_t globalDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_set_target_queue(mySerialDispatchQueue, globalDispatchQueue);
    //指定要變更執行優先級的dispatch queue為dispatch_set_target_queue方法的第一個參數,指定與要使用的執行優先級相同優先級的Global Dispatch Queue為第二個參數(目標)
    //第一個參數不可以指定為系統提供的Main Dispatch Queue 和 Global Dispatch Queue

 

4、dispatch_after

想在指定時間後執行處理的情況,可以使用 dispatch_after 方法來實現

[cpp]
double delayInSeconds = 2.0; 
   dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
   dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
       NSLog(@"waited  at least 2.0 seconds."); 
   }); 

 double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"waited  at least 2.0 seconds.");
    });

值得注意的是,dispatch_after方法並不是在指定時間後執行處理任務,而是在指定時間後追加處理到dispatch queue中,上面的代碼在2秒後用dispatch_after方法追加

block到Main Dispatch Queue中,因為Main Dispatch Queue在主線程的RunLoop中執行,所以比如每個1/60秒執行的RunLoop中,Block最快在2秒後執行,最慢在2秒+1/60

秒後執行,而且在Main Dispatch Queue中又大量處理追加或者主線程的處理本身有延時時,這個時間會更長。

 

dispatch_after這個方法的第二個參數指定要追加的dispatch queue,第三個參數指定要執行處理的Block,第一個參數是指定時間用的dispatch_time_t類型的值,在使用

dispatch_after的時候,編譯器會自動幫你生成這些代碼,只需修改delayInSeconds就可以了。

 

5、Dispatch Group

在追加到dispatch queue中的多個處理全部結束後想執行結束處理任務,這種情況會經常出現。只使用一個Serial Dispatch Queue時,只要將想執行的全部處理都追加到該

Serial Dispatch Queue種並在最後追加結束處理就可以實現。但是在使用Concurrent Dispatch Queue時或者同時使用多個dispatch queue時,就會有些復雜了,在這種情況下

就應該使用Dispatch Group

[cpp]
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
    dispatch_group_t group = dispatch_group_create(); 
     
    dispatch_group_async(group, queue, ^{NSLog(@"blk1");}); 
    dispatch_group_async(group, queue, ^{NSLog(@"blk2");}); 
    dispatch_group_async(group, queue, ^{NSLog(@"blk3");}); 
     
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
        NSLog(@"done"); 
    }); 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_group_t group = dispatch_group_create();
   
    dispatch_group_async(group, queue, ^{NSLog(@"blk1");});
    dispatch_group_async(group, queue, ^{NSLog(@"blk2");});
    dispatch_group_async(group, queue, ^{NSLog(@"blk3");});
   
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"done");
    });

因為向 Global Dispatch Queue即Concurrent Dispatch Queue追加處理任務,多個線程並行執行,所以追加處理任務的執行順序是不定的,執行時順序會發生變化,但是主線程中執行結果輸出done肯定是最後的。

   

下面稍微解釋一下上面的那段代碼,上面由3個輸出任務的block組成一個dispatch group,並把這個dispatch group添加到dispatch queue中執行,當dispatch group中的

block任務執行完畢後,dispatch_group_notify方法就會被執行到,所以它的第一個參數是group,表示其被監視。在追加到dispatch group中的全部執行處理任務執行結束後,

將第三個參數中的block任務添加到第二個參數的dispatch queue中執行,注意此時dispatch group中的所以執行任務已經執行結束了。

 

另外,在dispatch group中也可以使用 dispatch_group_wait方法僅等待全部處理執行結束。

[cpp]
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
    dispatch_group_t group = dispatch_group_create(); 
     
    dispatch_group_async(group, queue, ^{NSLog(@"blk1");}); 
    dispatch_group_async(group, queue, ^{NSLog(@"blk2");}); 
    dispatch_group_async(group, queue, ^{NSLog(@"blk3");}); 
     
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_group_t group = dispatch_group_create();
   
    dispatch_group_async(group, queue, ^{NSLog(@"blk1");});
    dispatch_group_async(group, queue, ^{NSLog(@"blk2");});
    dispatch_group_async(group, queue, ^{NSLog(@"blk3");});
   
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

在這個方法中的第二個參數指定等待時間,這裡使用DISPATCH_TIME_FOREVER意味著永久等待,只要屬於dispatch group中的處理尚未執行結束,就會一直等待,中途不能取消。

 

 

當然如同dispatch——after方法中那樣,也可以指定等待時間為1秒等等。

[cpp]
//這裡指定等待時間1s,即1s後查看dispatch group中的處理是否全部執行結束  
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC); 
    long result = dispatch_group_wait(group, time); 
    if (result == 0) { 
        //屬於dispatch group中的全部處理都執行結束  
    } 
    else { 
        //屬於dispatch group的某一個處理還在執行  
    } 

//這裡指定等待時間1s,即1s後查看dispatch group中的處理是否全部執行結束
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC);
    long result = dispatch_group_wait(group, time);
    if (result == 0) {
        //屬於dispatch group中的全部處理都執行結束
    }
    else {
        //屬於dispatch group的某一個處理還在執行
    }

 

[cpp]
//這裡也可以指定DISPATCH_TIME_NOW,則不用任何等待即可判斷屬於dispatch group中的處理是否全部執行結束  
   long result = dispatch_group_wait(group, DISPATCH_TIME_NOW); 

 //這裡也可以指定DISPATCH_TIME_NOW,則不用任何等待即可判斷屬於dispatch group中的處理是否全部執行結束
    long result = dispatch_group_wait(group, DISPATCH_TIME_NOW);

 

 6、dispatch_barrier_async

[cpp]
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
     
    dispatch_async(queue, ^{ 
        //表示執行數據讀取任務  
        NSLog(@"blk1_reading"); 
    }); 
    dispatch_async(queue, ^{ 
        NSLog(@"blk2_reading"); 
    }); 
     
    dispatch_async(queue, ^{ 
        //表示執行數據寫入處理任務  
        NSLog(@"blk1_writting"); 
    }); 
     
    dispatch_async(queue, ^{ 
        NSLog(@"blk3_reading"); 
    }); 
    dispatch_async(queue, ^{ 
        NSLog(@"blk4_reading"); 
    }); 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
   
    dispatch_async(queue, ^{
        //表示執行數據讀取任務
        NSLog(@"blk1_reading");
    });
    dispatch_async(queue, ^{
        NSLog(@"blk2_reading");
    });
   
    dispatch_async(queue, ^{
        //表示執行數據寫入處理任務
        NSLog(@"blk1_writting");
    });
   
    dispatch_async(queue, ^{
        NSLog(@"blk3_reading");
    });
    dispatch_async(queue, ^{
        NSLog(@"blk4_reading");
    });

 

如果像上面那樣簡單的在dispatch_async方法中添加寫入數據處理的任務,那麼根據Concurrent Dispatch Queue並行執行的性質,就很有可能不是按照上面的添加處理任務的

順序執行,那麼在blk3_reading 和 blk4_reading執行讀取數據的時候,blk1_writting進行寫入數據的處理還沒有執行到,那麼後兩次的讀取數據操作讀取到的數據就與期望中

的不符了。

解決這個問題的處理就是 使用 dispatch_barrier_async

 

[cpp]
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
    
   dispatch_async(queue, ^{ 
       //表示執行數據讀取任務  
       NSLog(@"blk1_reading"); 
   }); 
   dispatch_async(queue, ^{ 
       NSLog(@"blk2_reading"); 
   }); 
    
   dispatch_barrier_async(queue, ^{ 
       //表示執行數據寫入處理任務  
       NSLog(@"blk1_writting"); 
   }); 
    
   dispatch_async(queue, ^{ 
       NSLog(@"blk3_reading"); 
   }); 
   dispatch_async(queue, ^{ 
       NSLog(@"blk4_reading"); 
   }); 

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
   
    dispatch_async(queue, ^{
        //表示執行數據讀取任務
        NSLog(@"blk1_reading");
    });
    dispatch_async(queue, ^{
        NSLog(@"blk2_reading");
    });
   
    dispatch_barrier_async(queue, ^{
        //表示執行數據寫入處理任務
        NSLog(@"blk1_writting");
    });
   
    dispatch_async(queue, ^{
        NSLog(@"blk3_reading");
    });
    dispatch_async(queue, ^{
        NSLog(@"blk4_reading");
    });

使用dispatch_barrier_async方法,它會等待在它之前添加到 Concurrent Dispatch Queue的所有處理執行結束後,才執行該處理,然後等待該處理結束後,才接著處理後續添

加到Concurrent Dispatch Queue中的處理任務。當然在dispatch_barrier_async方法之前和之後添加的處理任務可以並發執行,即不保證執行順序,但是可以確保

dispatch_barrier_async方法添加的任務一定是只能同時執行一個,按其添加任務順序執行的,就是說,執行完blk1_reading和blk2_reading的讀取數據任務後,才是進行

blk1_writting的寫入數據任務,然後才是執行接著的讀取數據的任務。

 

 

7、dispatch——sync

 

 

dispatch_async方法中的async意味著“非同步”,就是將指定的block非同步的添加到dispatch qeueue中,dispatch_async方法不做任何等待。

dispatch_sync方法中的sync意味著“同步”,也就是將指定的block同步追加到dispatch queue中,在追加block的過程結束之前,dispatch_sync方法會一直等待。

一旦調用dispatch_sync,那麼在指定的處理執行結束之前,該方法不會返回,dispatch_sync方法可以簡化代碼,也可以說是簡易版的dispatch_group_wait方法

   

dispatch_sync方法使用簡單,但是容易引起死鎖

[cpp]
dispatch_queue_t queue = dispatch_get_main_queue(); 
    dispatch_sync(queue, ^{ 
        NSLog(@"引起死鎖!"); 
    }); 

dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        NSLog(@"引起死鎖!");
    });

上面的代碼在主線程中執行指定的block,並等待其執行結束,但是其實在主線程中就是在執行這些代碼,所以就造成了死鎖。

 

8、dispatch_apply

dispatch_apply 方法是 dispatch_sync 方法和Dispatch Group的關聯API,該方法按指定的次數將指定的Block追加到指定的Dispatch Queue中,並等待全部處理執行結束

[cpp]
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_apply(10, queue, ^(size_t index){ 
        NSLog(@"%zu",index); 
    }); 
    NSLog(@"done"); 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply(10, queue, ^(size_t index){
        NSLog(@"%zu",index);
    });
    NSLog(@"done");

因為是在Global Dispatch Queue中執行處理,所以各個處理的執行時間不定,也就是說輸出1 2 3 ...的順序不定。但是輸出結果done必定是在最後的位置上的。因為dispatch_apply會等待所以的處理任務執行結束。

dispatch_apply 中的第一個參數是重復次數,第二個參數是追加對象的Dispatch Queue,第三個參數為追加的處理block,注意帶參數

 

[cpp]
//假如對一個NSArray類對象的所有元素執行處理時,不必一個個編寫for循環  
    NSArray *array = [[NSArray alloc] initWithObjects:@"string1",@"string2",@"string3", nil]; 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_apply([array count], queue, ^(size_t index){ 
        NSLog(@"%zu : %@",index,[array objectAtIndex:index]); 
    }); 

//假如對一個NSArray類對象的所有元素執行處理時,不必一個個編寫for循環
    NSArray *array = [[NSArray alloc] initWithObjects:@"string1",@"string2",@"string3", nil];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply([array count], queue, ^(size_t index){
        NSLog(@"%zu : %@",index,[array objectAtIndex:index]);
    });

由於dispatch_apply方法也與dispatch_sync方法相同,會等待處理執行結束,因此推薦在dispatch_async函數中非同步的執行dispatch_apply方法。

例如:

[cpp]
NSArray *array = [[NSArray alloc] initWithObjects:@"string1",@"string2",@"string3", nil]; 
   dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
   //在Glocbal Dispatch Queue中非同步執行  
   dispatch_async(queue, ^{ 
        
       //等待dispatch_apply方法中的全部處理執行結束  
       dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
       dispatch_apply([array count], queue, ^(size_t index){ 
           NSLog(@"%zu : %@",index,[array objectAtIndex:index]); 
       }); 
        
       //dispatch_apply方法中的全部處理任務執行結束  
        
       dispatch_async(dispatch_get_main_queue(), ^{ 
          //在主線程中執行處理  
           NSLog(@"done"); 
       }); 
        
   }); 

 NSArray *array = [[NSArray alloc] initWithObjects:@"string1",@"string2",@"string3", nil];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //在Glocbal Dispatch Queue中非同步執行
    dispatch_async(queue, ^{
       
        //等待dispatch_apply方法中的全部處理執行結束
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_apply([array count], queue, ^(size_t index){
            NSLog(@"%zu : %@",index,[array objectAtIndex:index]);
        });
       
        //dispatch_apply方法中的全部處理任務執行結束
       
        dispatch_async(dispatch_get_main_queue(), ^{
           //在主線程中執行處理
            NSLog(@"done");
        });
       
    });

 

9、dispatch_suspend 和 dispatch_resume

[cpp]
//掛起指定的dispatch queue  
    dispatch_suspend(<#dispatch_object_t object#>) 
    //恢復指定的dispatch queue  
    dispatch_resume(<#dispatch_object_t object#>) 
    //這些方法對已經執行的處理沒有影響,掛起後,追加到dispatch queue中但尚未處理的在此之後停止執行,而恢復後則使得這些處理能夠繼續執行。 

//掛起指定的dispatch queue
    dispatch_suspend(<#dispatch_object_t object#>)
    //恢復指定的dispatch queue
    dispatch_resume(<#dispatch_object_t object#>)
    //這些方法對已經執行的處理沒有影響,掛起後,追加到dispatch queue中但尚未處理的在此之後停止執行,而恢復後則使得這些處理能夠繼續執行。
10、dispatch_once

dispatch_once方法保證在應用程序執行中只執行一次指定處理的API。

[cpp]
static dispatch_once_t onceToken; 
   dispatch_once(&onceToken, ^{ 
       //code to be executed once  
   }); 

 static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //code to be executed once
    });

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved