iOS主要知識(shí)總結(jié)(網(wǎng)絡(luò)與多線程——GCD)

u=1546308334,1185521960&fm=21&gp=0.jpg

GCD

簡(jiǎn)介

  • 1.旨在代替NSThread等線程技術(shù)
  • 2.能夠充分利用多核的特點(diǎn)
  • 3.用到的兩個(gè)核心概念:隊(duì)列(并發(fā)+串行)+任務(wù)(同步+異步)
  • 有一點(diǎn)需要注意:異步函數(shù)具有開啟線程的能力,而同步函數(shù)不會(huì)開啟線程

基本使用

  • 01 異步函數(shù)+并發(fā)隊(duì)列:開啟多條線程,并發(fā)執(zhí)行任務(wù)(最常用)
  • 02 異步函數(shù)+串行隊(duì)列:開啟一條線程,串行執(zhí)行任務(wù)
  • 03 同步函數(shù)+并發(fā)隊(duì)列:不開線程,在當(dāng)前線程里串行執(zhí)行任務(wù)
  • 04 同步函數(shù)+串行隊(duì)列:不開線程,在當(dāng)前線程里串行執(zhí)行任務(wù)
  • 05 異步函數(shù)+主隊(duì)列:不開線程,在主線程中串行執(zhí)行任務(wù)
  • 06 同步函數(shù)+主隊(duì)列:不開線程,串行執(zhí)行任務(wù)(注意死鎖發(fā)生)

常用代碼示例:

  • 1.異步+并發(fā)
//異步+并發(fā)(創(chuàng)建多個(gè)線程,并發(fā)執(zhí)行)
-(void)asyncConcurrent{
    /*
     第一個(gè)參數(shù):C語(yǔ)言的字符串  給隊(duì)列起一個(gè)名字
     第二個(gè)參數(shù):類型
     DISPATCH_QUEUE_CONCURRENT  并發(fā)隊(duì)列
     DISPATCH_QUEUE_SERIAL      串行隊(duì)列
     */
    //創(chuàng)建并發(fā)隊(duì)列
    dispatch_queue_t queue=dispatch_queue_create("wujian.com.con", DISPATCH_QUEUE_CONCURRENT);
    //封裝任務(wù)并把任務(wù)添加到隊(duì)列當(dāng)中
    dispatch_async(queue, ^{
        NSLog(@"1--------------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2--------------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3--------------%@",[NSThread currentThread]);
    });
}
  • 2.異步+串行
-(void)asyncSerial{
    NSLog(@"開始---");
    dispatch_queue_t queue=dispatch_queue_create("lslslslsll.com", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"1--------------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2--------------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3--------------%@",[NSThread currentThread]);
    });
    NSLog(@"結(jié)束---");
}

注意:此處運(yùn)行會(huì)發(fā)現(xiàn)先打印“開始--”,然后打印“結(jié)束--”,在這之后再處理這兩者中間的具體任務(wù),這其實(shí)是異步函數(shù)的一個(gè)特點(diǎn),異步函數(shù)采用的是回調(diào)的機(jī)制,像打印這種簡(jiǎn)單的操作,就直接執(zhí)行了,而對(duì)于異步函數(shù)里的任務(wù),在其他操作完成之后再去執(zhí)行,這樣做會(huì)防止死鎖的發(fā)生。

  • 3.同步+串行(在當(dāng)前線程中串行執(zhí)行)
-(void)syncSerial{
    dispatch_queue_t queue=dispatch_queue_create("com.sssss", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        NSLog(@"1--------------%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2--------------%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3--------------%@",[NSThread currentThread]);
    });

}
  • 4.同步+并發(fā)(不會(huì)創(chuàng)建線程,在當(dāng)前線程中串行執(zhí)行)
-(void)syncConcurrent{
    //自己創(chuàng)建的并發(fā)隊(duì)列
//    dispatch_queue_t queue=dispatch_queue_create("ldsjfl.com", DISPATCH_QUEUE_CONCURRENT);
    //獲取全局隊(duì)列(用法與上面幾乎無異)
    dispatch_queue_t queue=dispatch_get_global_queue(0, 0);
    dispatch_sync(queue, ^{
        NSLog(@"1--------------%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2--------------%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3--------------%@",[NSThread currentThread]);
    });
}
  • 5.異步+主隊(duì)列(與主線程相關(guān)):在主線程中串行執(zhí)行,由于異步的執(zhí)行特點(diǎn),所以不會(huì)造成死鎖
-(void)asyncMainQueue{
    dispatch_queue_t queue=dispatch_get_main_queue();
    dispatch_async(queue, ^{
        NSLog(@"1--------------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2--------------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3--------------%@",[NSThread currentThread]);
    });

}
  • 6.同步+主隊(duì)列:會(huì)造成死鎖(在子線程中不會(huì)有死鎖發(fā)生)
  • 如果主隊(duì)列中有任務(wù),那么主隊(duì)列會(huì)安排主線程來執(zhí)行當(dāng)前隊(duì)列中的任務(wù),但是在調(diào)度之前會(huì)先檢查主線程的狀態(tài),如果主線程在忙那么就暫停調(diào)度隊(duì)列中的任務(wù),等到主線程空閑的時(shí)候再調(diào)度(而此處的主線程剛好在執(zhí)行自身這個(gè)函數(shù)) (只有主隊(duì)列關(guān)心主線程忙不忙)
-(void)syncMainQueue{
    NSLog(@"ssss");
    dispatch_queue_t queue=dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        NSLog(@"1--------------%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2--------------%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3--------------%@",[NSThread currentThread]);
    });

}

獲得串行隊(duì)列的兩種途徑

  • 1.通過函數(shù)自己創(chuàng)建
dispatch_queue_t queue=dispatch_queue_create("lslslslsll.com", DISPATCH_QUEUE_SERIAL);
  • 2.獲得系統(tǒng)的主隊(duì)列
dispatch_queue_t queue=dispatch_get_main_queue();

獲得全局隊(duì)列的兩種途徑

  • 1.通過函數(shù)自己創(chuàng)建
    dispatch_queue_t queue=dispatch_queue_create("wujian.com.con", DISPATCH_QUEUE_CONCURRENT);
  • 2.獲得系統(tǒng)的全局隊(duì)列(建議使用這種方法)
//第一個(gè)參數(shù)是隊(duì)列的優(yōu)先級(jí),可以傳0表示默認(rèn),第二個(gè)參數(shù)暫時(shí)用不上,是蘋果預(yù)留的參數(shù),傳0即可。
    dispatch_queue_t queue=dispatch_get_global_queue(0, 0);

GCD中的線程通信

- (void)viewDidLoad {
    [super viewDidLoad];

    //開子線程
    //01 獲得全局并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    //02 使用異步函數(shù)+并發(fā)隊(duì)列
    dispatch_async(queue, ^{

        //03 確定URL
        NSURL *url = [NSURL URLWithString:@"http://XXXXX.jpg"];

        //04 把圖片的二進(jìn)制數(shù)據(jù)下載到本地
        NSData *data = [NSData dataWithContentsOfURL:url];

        //05 轉(zhuǎn)換格式
        UIImage *image = [UIImage imageWithData:data];
        NSLog(@"耗時(shí)操作---%@",[NSThread currentThread]);

        //06 顯示圖片(回到主線程,其實(shí)是一種嵌套的模式)
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = image;
              NSLog(@"UI操作---%@",[NSThread currentThread]);
        });
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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