GCD

GCD

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

  • 任務(wù)使用block封裝, 沒(méi)有參數(shù), 沒(méi)有返回值
  • 執(zhí)行任務(wù)的函數(shù):
    同步 dispatch_sync :
    必須等待當(dāng)前語(yǔ)句執(zhí)行完畢,才會(huì)執(zhí)行下一條語(yǔ)句;
    不會(huì)開(kāi)啟線程;
    在當(dāng)前的block執(zhí)行任務(wù).
    異步 dispathc_asyc:
    不必等待當(dāng)前語(yǔ)句執(zhí)行完畢, 就可以一執(zhí)行下一條語(yǔ)句;
    會(huì)開(kāi)啟線程執(zhí)行block中的任務(wù);
    異步是對(duì)線程的代名詞.
  • 隊(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)度對(duì)個(gè)任務(wù)
    主隊(duì)列: dispatch_get_main_queue();
    專門在主線程調(diào)度任務(wù)的隊(duì)列
    不會(huì)開(kāi)啟線程
    在主線程空閑的時(shí)候才會(huì)調(diào)度任務(wù)在主線程執(zhí)行

總結(jié):

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

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

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

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

- (void)delay {
    /**
     從現(xiàn)在開(kāi)始,經(jīng)過(guò)多少納秒,由"隊(duì)列"調(diào)度異步執(zhí)行 block 中的代碼
     參數(shù)
     1. when    從現(xiàn)在開(kāi)始,經(jīng)過(guò)多少納秒
     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í)候,在程序開(kāi)發(fā)中,有些代碼只想從程序啟動(dòng)就只執(zhí)行一次,典型的應(yīng)用場(chǎng)景就是“單例”

- (void)once{
    NSLog(@"來(lái)了");
    //蘋(píng)果提供的一次執(zhí)行機(jī)制, 不僅執(zhí)行一次, 而且線程安全
    static dispatch_once_t onceToken;
    
    NSLog(@"%ld",onceToken);
    //蘋(píng)果推薦使用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)聽(tīng)所有任務(wù)完成
    dispatch_group_notify(group, q, ^{
        NSLog(@"OVER %@", [NSThread currentThread]);
    });

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

另一種寫(xiě)法:

// 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 必須成對(duì)出現(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)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容