GCD

GCD

概念: 將任務(wù)添加到隊(duì)列中, 并且指定執(zhí)行任務(wù)的函數(shù);

  • 任務(wù)使用block封裝, 沒有參數(shù), 沒有返回值
  • 執(zhí)行任務(wù)的函數(shù):
    同步 dispatch_sync :
    必須等待當(dāng)前語句執(zhí)行完畢,才會執(zhí)行下一條語句;
    不會開啟線程;
    在當(dāng)前的block執(zhí)行任務(wù).
    異步 dispathc_asyc:
    不必等待當(dāng)前語句執(zhí)行完畢, 就可以一執(zhí)行下一條語句;
    會開啟線程執(zhí)行block中的任務(wù);
    異步是對線程的代名詞.
  • 隊(duì)列-負(fù)責(zé)調(diào)度任務(wù):
    串行隊(duì)列: dispatch_queue_create("jianshu", NULL);
    一次只能調(diào)度一個(gè)任務(wù)
    并發(fā)隊(duì)列: dispatch_queue_create("itheima", DISPATCH_QUEUE_CONCURRENT);
    一次可以調(diào)度對個(gè)任務(wù)
    主隊(duì)列: dispatch_get_main_queue();
    專門在主線程調(diào)度任務(wù)的隊(duì)列
    不會開啟線程
    在主線程空閑的時(shí)候才會調(diào)度任務(wù)在主線程執(zhí)行

總結(jié):

  • 開不開線程是由執(zhí)行任務(wù)的函數(shù)決定的:
    同步不開線程;
    異步開線程.
  • 開幾條線程是由隊(duì)列決定的:
    串行隊(duì)列開一條;
    并發(fā)隊(duì)列開多條線程, 具體數(shù)量由底層線程池決定;
全局隊(duì)列:

是系統(tǒng)為了方便程序員開發(fā)提供的, 與并發(fā)隊(duì)列效果一直, 但也有區(qū)別:

  • 全局隊(duì)列: 沒有名稱, 無論MRC或者ARC都不需要考慮釋放, 日常開發(fā)建議使用全局隊(duì)列.
  • 并發(fā)隊(duì)列:
    1. 有名稱, 和NSThread的name屬性類似;
    2. 如果在 MRC 開發(fā)時(shí),需要使用 dispatch_release(q); 釋放相應(yīng)的對象
    3. dispatch_barrier 必須使用自定義的并發(fā)隊(duì)列
    4. 開發(fā)第三方框架時(shí),建議使用并發(fā)隊(duì)列
延遲操作:

dispatch_after(dispatch_time_t when, dispatch_queue_t _Nonnull queue, ^(void)block)

- (void)delay {
    /**
     從現(xiàn)在開始,經(jīng)過多少納秒,由"隊(duì)列"調(diào)度異步執(zhí)行 block 中的代碼
     參數(shù)
     1. when    從現(xiàn)在開始,經(jīng)過多少納秒
     2. queue   隊(duì)列
     3. block   異步執(zhí)行的任務(wù)
     */
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));
    void (^task)() = ^ {
        NSLog(@"%@", [NSThread currentThread]);
    };
    // 主隊(duì)列
//    dispatch_after(when, dispatch_get_main_queue(), task);
    // 全局隊(duì)列
//    dispatch_after(when, dispatch_get_global_queue(0, 0), task);
    // 串行隊(duì)列
    dispatch_after(when, dispatch_queue_create("itheima", NULL), task);

    NSLog(@"come here");
}
一次執(zhí)行:

有的時(shí)候,在程序開發(fā)中,有些代碼只想從程序啟動就只執(zhí)行一次,典型的應(yīng)用場景就是“單例”

- (void)once{
    NSLog(@"來了");
    //蘋果提供的一次執(zhí)行機(jī)制, 不僅執(zhí)行一次, 而且線程安全
    static dispatch_once_t onceToken;
    
    NSLog(@"%ld",onceToken);
    //蘋果推薦使用GCD 一次執(zhí)行, 效率高, 不要使用互斥鎖, 效率低
    dispatch_once(&onceToken, ^{
        
        NSLog(@"執(zhí)行了%@", [NSThread currentThread]);
    });
    
}

- (void)testOnce
{
    for (int i = 0; i< 10; i++) {
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
           
            [self once];
        });
    }
}
調(diào)度組:

常規(guī)使用:

- (void)group1 {

    // 1. 調(diào)度組
    dispatch_group_t group = dispatch_group_create();

    // 2. 隊(duì)列
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);

    // 3. 將任務(wù)添加到隊(duì)列和調(diào)度組
    dispatch_group_async(group, q, ^{
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"任務(wù) 1 %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, q, ^{
        NSLog(@"任務(wù) 2 %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, q, ^{
        NSLog(@"任務(wù) 3 %@", [NSThread currentThread]);
    });

    // 4. 監(jiān)聽所有任務(wù)完成
    dispatch_group_notify(group, q, ^{
        NSLog(@"OVER %@", [NSThread currentThread]);
    });

    // 5. 判斷異步
    NSLog(@"come here");
}

另一種寫法:

// MARK: - 調(diào)度組 2
- (void)group2 {
    // 1. 調(diào)度組
    dispatch_group_t group = dispatch_group_create();

    // 2. 隊(duì)列
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);

    // dispatch_group_enter & dispatch_group_leave 必須成對出現(xiàn)
    dispatch_group_enter(group);
    dispatch_group_async(group, q, ^{
        NSLog(@"任務(wù) 1 %@", [NSThread currentThread]);

        // dispatch_group_leave 必須是 block 的最后一句
        dispatch_group_leave(group);
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, q, ^{
        NSLog(@"任務(wù) 2 %@", [NSThread currentThread]);

        // dispatch_group_leave 必須是 block 的最后一句
        dispatch_group_leave(group);
    });

    // 4. 阻塞式等待調(diào)度組中所有任務(wù)執(zhí)行完畢
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    // 5. 判斷異步
    NSLog(@"OVER %@", [NSThread currentThread]);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容