多線程-GCD特性

這篇文章將演示GCD三個(gè)特性的使用:
1.延遲執(zhí)行
2.一次性執(zhí)行
3.調(diào)度組

  • 延遲執(zhí)行

示例代碼:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    NSLog(@"begin");
    // 延遲執(zhí)行
    /*
        參數(shù)1: <#delayInSeconds#>   --> 延遲多少時(shí)間執(zhí)行
        參數(shù)2: dispatch_queue_t  --> 執(zhí)行操作的隊(duì)列
        參數(shù)3: dispatch_block_t  --> 執(zhí)行的任務(wù)
        異步執(zhí)行,并不會(huì)卡死主線程
     */
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        NSLog(@"%s",__func__);
    });
    NSLog(@"end");
    
}

@end

LOG信息:

2016-08-21 13:39:05.720 延遲執(zhí)行[23451:3109328] begin
2016-08-21 13:39:05.721 延遲執(zhí)行[23451:3109328] end
2016-08-21 13:39:10.722 延遲執(zhí)行[23451:3109328] __41-[ViewController touchesBegan:withEvent:]_block_invoke
  • 一次性執(zhí)行

示例代碼:

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    // 一次性執(zhí)行  (線程安全,只執(zhí)行一次)
    for (int i = 0; i < 10; i ++) {

        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSLog(@"%s",__func__);
        });
        
    }

}

@end

因?yàn)檫@種一次性執(zhí)行的特性,常常被使用在單例設(shè)計(jì)模式中,并且性能突出
http://www.itdecent.cn/p/1da234f4b551

  • 調(diào)度組

有時(shí)候需要在多個(gè)異步任務(wù)都執(zhí)行完成之后繼續(xù)做某些事情,比如下載歌曲,等所有的歌曲都下載完畢之后,轉(zhuǎn)到主線程提示用戶,通過GCD的調(diào)度組功能即可實(shí)現(xiàn)這種需求

參數(shù)1:<#dispatch_group_t group#>  -> 調(diào)度組
參數(shù)2:<#dispatch_queue_t queue#>  -> 隊(duì)列
參數(shù)3:<#^(void)block#>            -> 任務(wù)

dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)

示例代碼:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
// 調(diào)度組使用

// 需求: 任務(wù)1&任務(wù)2&任務(wù)3 --> 全部都完成后(不限制執(zhí)行順序),提示完成
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    // 1.需要執(zhí)行的任務(wù)
    dispatch_block_t task1 = ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"操作1");
    };
    dispatch_block_t task2 = ^{
        [NSThread sleepForTimeInterval:5];
        NSLog(@"操作2");
    };
    dispatch_block_t task3 = ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"操作3");
    };
    
    // 2.創(chuàng)建調(diào)度組
    dispatch_group_t group = dispatch_group_create();
    
    // 3.添加到調(diào)度組中
    /*    dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
            參數(shù)1:<#dispatch_group_t group#>  -> 調(diào)度組
            參數(shù)2:<#dispatch_queue_t queue#>  -> 隊(duì)列(處理任務(wù)執(zhí)行的隊(duì)列)
            參數(shù)3:<#^(void)block#>            -> 任務(wù)
     */
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), task1);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), task2);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), task3);
    
    // 4.調(diào)度組內(nèi)的任務(wù)執(zhí)行完畢后回到主線程通知
    /*     dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
             參數(shù)1:<#dispatch_group_t group#>  -> 調(diào)度組
             參數(shù)2:<#dispatch_queue_t queue#>  -> 隊(duì)列(參數(shù)3內(nèi)的代碼執(zhí)行隊(duì)列)
             參數(shù)3:<#^(void)block#>            -> 任務(wù)
     
     */
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"執(zhí)行完畢");
    });
}

@end

上述調(diào)度組的示例代碼中,通過創(chuàng)建任務(wù),調(diào)度組,在通過調(diào)度組異步處理任務(wù)時(shí),將任務(wù)自動(dòng)放入調(diào)度組中執(zhí)行

調(diào)度組的原理:

- (void)demo{
    
    // 創(chuàng)建調(diào)度組
    dispatch_group_t group = dispatch_group_create();
    
    // 相當(dāng)于任務(wù)1
    // 將后面的代碼放入調(diào)度組中執(zhí)行
    dispatch_group_enter(group);
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"操作1");
        //任務(wù)執(zhí)行完畢后離開調(diào)度組
        dispatch_group_leave(group);
    });
    
    // 相當(dāng)于任務(wù)2
    dispatch_group_enter(group);
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:3];
        dispatch_group_leave(group);
        NSLog(@"操作2");
    });
    
    // 相當(dāng)于任務(wù)3
    dispatch_group_enter(group);
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"操作3");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務(wù)執(zhí)行完畢");
    });
    
    
}

調(diào)度組的實(shí)現(xiàn)過程:

1.通過dispatch_group_enter(group);手動(dòng)讓后面的代碼進(jìn)入調(diào)度組
2.當(dāng)任務(wù)執(zhí)行完畢后,通過dispatch_group_leave(group);離開調(diào)度組
3.當(dāng)所有任務(wù)執(zhí)行完畢后,調(diào)用dispatch_group_notify做最后的處理
dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 從哪說起呢? 單純講多線程編程真的不知道從哪下嘴。。 不如我直接引用一個(gè)最簡單的問題,以這個(gè)作為切入點(diǎn)好了 在ma...
    Mr_Baymax閱讀 2,912評論 1 17
  • 原文:http://www.cocoachina.com/ios/20170707/19769.html 本文主要...
    冬的天閱讀 2,419評論 0 12
  • 目錄 一、基本概念1.多線程2.串行和并行, 并發(fā)3.隊(duì)列與任務(wù)4.同步與異步5.線程狀態(tài)6.多線程方案 二、GC...
    BohrIsLay閱讀 1,700評論 5 12
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評論 19 139
  • 滴滴出行- 故事的開頭是一群廣告人熬夜加班準(zhǔn)備開車閃人時(shí),一位較清醒的女同事提出她來當(dāng)司機(jī),其余人都知道她剛拿駕照...
    LV_aab5閱讀 170評論 0 0

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