GCD 常見用法

一、延遲執行併發

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    // 1秒後異步執行這裏的代碼...

});

二、後臺執行app

dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

三、主線程執行異步

dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

四、併發執行迭代循環async

//GCD提供了一個簡化方法叫作dispatch_apply,當咱們把這個方法放到併發隊列中執行時,這個函數會調用單一block屢次,並平行運算,而後等待全部運算結束。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(count, queue, ^(size_t i) {
   NSLog("%d",i);
});

五、掛起和恢復隊列函數

//有時候,咱們不想讓隊列中的某些任務立刻執行,這時咱們能夠經過掛起操做來阻止一個隊列中將要執行的任務。當須要掛起隊列時,使用dispatch_suspend方法;恢復隊列時,使用dispatch_resume方法。調用dispatch_suspend會增長隊列掛起的引用計數,而調用dispatch_resume則會減小引用計數,當引用計數大於0時,隊列會保持掛起狀態。所以,這隊列的掛起和恢復中,咱們須要當心使用以免引用計數計算錯誤的出現。
dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
//掛起隊列
dispatch_suspend(myQueue);
//恢復隊列
dispatch_resume(myQueue);

//執行掛起操做不會對已經開始執行的任務起做用,它僅僅只會阻止將要進行可是還未開始的任務。

六、信號量:在程序開發中,有時候咱們不想使用異步方式,例如咱們想要調用函數後馬上獲取結果值的時候,而後進行後續的數據操做。 這個時候須要信號量來等待返回結果,而後等到結果返回,從而進行後續處理。spa

信號量的做用是控制多個任務對有限數量資源的訪問。一個dispatch semaphore就像一個普通訊號的例外。當資源可用時,獲取dispatch semaphore的時間比獲取傳統的系統信號量要更少。這是由於GCD不調用這個特殊狀況下的內核。惟一的一次須要在內核中調用的狀況是,當資源不可用且系統須要在中止你的線程直到獲取信號。舉例來講更容易理解,若是你建立了一個有着兩個資源的信號量,那同時最多隻能有兩個線程能夠訪問臨界區。其餘想使用資源的線程必須在FIFO隊列裏等待。
// 建立一個信號量
dispatch_semaphore_t fd_sema = dispatch_semaphore_create(0);
// 等待一個空閒的文件描述符
dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER);
fd = open("/etc/services", O_RDONLY);
// 當完成時,釋放掉文件描述符
close(fd);
dispatch_semaphore_signal(fd_sema);

七、建立單例模式線程

+ (LYServiceInterface *) shareacWebService {
    static LYServiceInterface *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[LYServiceInterface alloc] init];
    });
    return sharedInstance;
}

八、倒計時code

__block NSInteger timeOut = 60;//倒計時時間
    dispatch_queue_t queue    = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer  = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1*NSEC_PER_SEC, 0);//每秒執行
    self.getCodeBtn.userInteractionEnabled = false;
    dispatch_source_set_event_handler(_timer, ^{
        if (timeOut <= 0) {
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //設置時間
                [self.getCodeBtn setTitle:@"獲取驗證碼" forState:UIControlStateNormal];
                self.getCodeBtn.userInteractionEnabled = true;
            });
        } else {
            NSString  *strTime = [NSString stringWithFormat:@"%ld 秒",(long)timeOut];
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.getCodeBtn setTitle:strTime forState:UIControlStateNormal];
            });
            timeOut--;
        }
    });
    dispatch_resume(_timer);

Dispatch groups是阻塞線程直到一個或多個任務完成的一種方式。在那些須要等待任務完成才能執行某個處理的時候,你可使用這個方法。Dispatch Group會在整個組的任務都完成時通知你,這些任務能夠是同步的,也能夠是異步的,即使在不一樣的隊列也行。並且在整個組的任務都完成時,Dispatch Group能夠用同步的或者異步的方式通知你。當group中全部的任務都完成時,GCD 提供了兩種通知方式。orm

九、異步執行2個耗時操做,等2個異步操做都執行完畢,再回到主線程執行操做隊列

dispatch_group_t group =  dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執行1個耗時的異步操做

});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執行1個耗時的異步操做

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    // 等前面的異步操做都執行完畢後,回到主線程...

});

十、dispatch_group_wait。它會阻塞當前線程,直到組裏面全部的任務都完成或者等到某個超時發生。

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, ^{
// 一些異步操做
});
//若是在全部任務完成前超時了,該函數會返回一個非零值。
//你能夠對此返回值作條件判斷以肯定是否超出等待週期;
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// 不須要group後將作釋放操做
dispatch_release(group);
相關文章
相關標籤/搜索