iOS開發(fā)多線程篇—GCD介紹?

  • 版權(quán)聲明:本文為博主原創(chuàng)文章存淫,未經(jīng)博主允許不得轉(zhuǎn)載耘斩。

一、簡單介紹

1.什么是GCD桅咆?

全稱是Grand Central Dispatch括授,可譯為“牛逼的中樞調(diào)度器”

純C語言,提供了非常多強(qiáng)大的函數(shù)

2.GCD的優(yōu)勢

GCD是蘋果公司為多核的并行運(yùn)算提出的解決方案

GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核岩饼、四核)

GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程荚虚、調(diào)度任務(wù)、銷毀線程)

程序員只需要告訴GCD想要執(zhí)行什么任務(wù)籍茧,不需要編寫任何線程管理代碼

3.提示

  • (1)GCD存在于libdispatch.dylib這個(gè)庫中版述,這個(gè)調(diào)度庫包含了GCD的所有的東西,但任何IOS程序寞冯,默認(rèn)就加載了這個(gè)庫渴析,在程序運(yùn)行的過程中會(huì)動(dòng)態(tài)的加載這個(gè)庫,不需要我們手動(dòng)導(dǎo)入吮龄。

點(diǎn)擊+a按鈕俭茧,可以導(dǎo)入框架。


  • (2)GCD是純C語言的漓帚,因此我們在編寫GCD相關(guān)代碼的時(shí)候母债,面對的函數(shù),而不是方法胰默。

  • (3)GCD中的函數(shù)大多數(shù)都以dispatch開頭场斑。

二漓踢、任務(wù)和隊(duì)列

  • GCD中有2個(gè)核心概念:

(1)任務(wù):執(zhí)行什么操作

(2)隊(duì)列:用來存放任務(wù)

  • GCD的使用就2個(gè)步驟

(1)定制任務(wù)

(2)確定想做的事情

將任務(wù)添加到隊(duì)列中牵署,GCD會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出漏隐,放到對應(yīng)的線程中執(zhí)行

提示:任務(wù)的取出遵循隊(duì)列的FIFO原則:先進(jìn)先出,后進(jìn)后出

三奴迅、執(zhí)行任務(wù)

1.GCD中有2個(gè)用來執(zhí)行任務(wù)的函數(shù)

說明:把右邊的參數(shù)(任務(wù))提交給左邊的參數(shù)(隊(duì)列)進(jìn)行執(zhí)行青责。

  • (1)用同步的方式執(zhí)行任務(wù) dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

參數(shù)說明:

queue:隊(duì)列

block:任務(wù)

  • (2)用異步的方式執(zhí)行任務(wù) dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
2.同步和異步的區(qū)別

同步:在當(dāng)前線程中執(zhí)行

異步:在另一條線程中執(zhí)行

四、隊(duì)列

  • 1.隊(duì)列的類型
    GCD的隊(duì)列可以分為2大類型:
(1)并發(fā)隊(duì)列(Concurrent Dispatch Queue)

可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效

(2)串行隊(duì)列(Serial Dispatch Queue)

讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后取具,再執(zhí)行下一個(gè)任務(wù))

  • 2.補(bǔ)充說明
有4個(gè)術(shù)語比較容易混淆:同步脖隶、異步、并發(fā)暇检、串行
同步和異步?jīng)Q定了要不要開啟新的線程

同步:在當(dāng)前線程中執(zhí)行任務(wù)产阱,不具備開啟新線程的能力

異步:在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力

*******************************************************

并發(fā)和串行決定了任務(wù)的執(zhí)行方式

并發(fā):多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行

串行:一個(gè)任務(wù)執(zhí)行完畢后块仆,再執(zhí)行下一個(gè)任務(wù)

  • 3.串行隊(duì)列
GCD中獲得串行有2種途徑:

(1)使用dispatch_queue_create函數(shù)創(chuàng)建串行隊(duì)列

dispatch_queue_t  dispatch_queue_create(const char *label,  dispatch_queue_attr_t attr); 
// 隊(duì)列名稱构蹬, 隊(duì)列屬性,一般用NULL即可```

示例:

```objc
dispatch_queue_t queue = dispatch_queue_create("wendingding", NULL); // 創(chuàng)建

dispatch_release(queue); // 非ARC需要釋放手動(dòng)創(chuàng)建的隊(duì)列```

 

(2)使用主隊(duì)列(跟主線程相關(guān)聯(lián)的隊(duì)列)

>主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列,放在主隊(duì)列中的任務(wù)悔据,都會(huì)放到主線程中執(zhí)行

>使用`dispatch_get_main_queue()`獲得主隊(duì)列

示例:
```objc
dispatch_queue_t queue = dispatch_get_main_queue();
  • 4.并發(fā)隊(duì)列

GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列庄敛,供整個(gè)應(yīng)用使用,不需要手動(dòng)創(chuàng)建

使用dispatch_get_global_queue函數(shù)獲得全局的并發(fā)隊(duì)列

dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags); 
// 此參數(shù)暫時(shí)無用科汗,用0即可```

示例:

這個(gè)參數(shù)是留給以后用的藻烤,暫時(shí)用不上,傳個(gè)0头滔。
第一個(gè)參數(shù)為優(yōu)先級(jí)怖亭,這里選擇默認(rèn)的。獲取一個(gè)全局的默認(rèn)優(yōu)先級(jí)的并發(fā)隊(duì)列坤检。

```objc
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
// 獲得全局并發(fā)隊(duì)列```

![](http://upload-images.jianshu.io/upload_images/838345-0460fe057e6db829.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


```objc
//說明:全局并發(fā)隊(duì)列的優(yōu)先級(jí)

#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)

#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺(tái)```


- 5.各種隊(duì)列的執(zhí)行效果

![](http://upload-images.jianshu.io/upload_images/838345-6eb851f19d7f67e1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


###五依许、代碼示例

- (1)用異步函數(shù)往并發(fā)隊(duì)列中添加任務(wù)


```objc
//
//  BBViewController.m
//  GCD的使用
//
//  Created by Biao on 16/6/12.
//  Copyright ? 2016年 Biao. All rights reserved.
//


#import "BBViewController.h"

@interface BBViewController ()

@end

@implementation BBViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //1.獲得全局的并發(fā)隊(duì)列
   dispatch_queue_t queue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.添加任務(wù)到隊(duì)列中,就可以執(zhí)行任務(wù)
    //異步函數(shù):具備開啟新線程的能力
    dispatch_async(queue, ^{
        NSLog(@"下載圖片1----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下載圖片2----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下載圖片2----%@",[NSThread currentThread]);
    });
//打印主線程
    NSLog(@"主線程----%@",[NSThread mainThread]);
    
}

@end```



![](http://upload-images.jianshu.io/upload_images/838345-07c0caca613ccd19.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

######總結(jié):同時(shí)開啟三個(gè)子線程

- (2)用異步函數(shù)往串行隊(duì)列中添加任務(wù)

```objc
//
//  BBViewController.m
//  GCD的使用
//
//  Created by Biao on 16/6/12.
//  Copyright ? 2016年 Biao. All rights reserved.
//

#import "BBViewController.h"

@interface BBViewController ()

@end

@implementation BBViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //打印主線程
    NSLog(@"主線程----%@",[NSThread mainThread]);
    
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t  queue= dispatch_queue_create("wendingding", NULL);
    //第一個(gè)參數(shù)為串行隊(duì)列的名稱缀蹄,是c語言的字符串
    //第二個(gè)參數(shù)為隊(duì)列的屬性峭跳,一般來說串行隊(duì)列不需要賦值任何屬性,所以通常傳空值(NULL)
    
    //2.添加任務(wù)到隊(duì)列中執(zhí)行
    dispatch_async(queue, ^{
        NSLog(@"下載圖片1----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下載圖片2----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"下載圖片2----%@",[NSThread currentThread]);
    });
    
    //3.釋放資源
//    dispatch_release(queue);
}

@end```

![](http://upload-images.jianshu.io/upload_images/838345-5bb5383dd2e04d43.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

######總結(jié):會(huì)開啟線程缺前,但是只開啟一個(gè)線程

- (3)用同步函數(shù)往并發(fā)隊(duì)列中添加任務(wù)

```objc
//
//  BBViewController.m
//  GCD的使用
//
//  Created by Biao on 16/6/12.
//  Copyright ? 2016年 Biao. All rights reserved.
//

#import "BBViewController.h"

@interface BBViewController ()

@end

@implementation BBViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    /**
     *  用同步函數(shù)往并發(fā)隊(duì)列中添加任務(wù)
     */
        
        //打印主線程
        NSLog(@"主線程----%@",[NSThread mainThread]);
        
        //創(chuàng)建串行隊(duì)列
        dispatch_queue_t  queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        
        //2.添加任務(wù)到隊(duì)列中執(zhí)行
        dispatch_sync(queue, ^{
            NSLog(@"下載圖片1----%@",[NSThread currentThread]);
        });
        dispatch_sync(queue, ^{
            NSLog(@"下載圖片2----%@",[NSThread currentThread]);
        });
        dispatch_sync(queue, ^{
            NSLog(@"下載圖片3----%@",[NSThread currentThread]);
        });
    
}

@end```

![](http://upload-images.jianshu.io/upload_images/838345-2e2123a9fa341238.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


######總結(jié):不會(huì)開啟新的線程蛀醉,并發(fā)隊(duì)列失去了并發(fā)的功能

- (4)用同步函數(shù)往串行隊(duì)列中添加任務(wù)

```objc
//
//  BBViewController.m
//  GCD的使用
//
//  Created by Biao on 16/6/12.
//  Copyright ? 2016年 Biao. All rights reserved.
//

#import "BBViewController.h"

@interface BBViewController ()

@end

@implementation BBViewController

/**
 *用同步函數(shù)往串行隊(duì)列中添加任務(wù)
 */
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"用同步函數(shù)往串行隊(duì)列中添加任務(wù)");
    //打印主線程
    NSLog(@"主線程----%@",[NSThread mainThread]);
    
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t  queue= dispatch_queue_create("wendingding", NULL);
    
    //2.添加任務(wù)到隊(duì)列中執(zhí)行
    dispatch_sync(queue, ^{
        NSLog(@"下載圖片1----%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"下載圖片2----%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"下載圖片3----%@",[NSThread currentThread]);
    });
}


@end```



![](http://upload-images.jianshu.io/upload_images/838345-9b6bdbe0fbc56294.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

######總結(jié):不會(huì)開啟新的線程

- (5)補(bǔ)充

>補(bǔ)充:隊(duì)列名稱的作用:

將來調(diào)試的時(shí)候,可以看得出任務(wù)是在哪個(gè)隊(duì)列中執(zhí)行的衅码。

![](http://upload-images.jianshu.io/upload_images/838345-3410823bf26164dc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



- (6)小結(jié)

>說明:同步函數(shù)不具備開啟線程的能力拯刁,無論是什么隊(duì)列都不會(huì)開啟線程;異步函數(shù)具備開啟線程的能力逝段,開啟幾條線程由隊(duì)列決定(串行隊(duì)列只會(huì)開啟一條新的線程垛玻,并發(fā)隊(duì)列會(huì)開啟多條線程)割捅。

######同步函數(shù):

>(1)并發(fā)隊(duì)列:不會(huì)開線程

>(2)串行隊(duì)列:不會(huì)開線程

######異步函數(shù):

>(1)并發(fā)隊(duì)列:能開啟N條線程

>(2)串行隊(duì)列:開啟1條線程

######補(bǔ)充:


>凡是函數(shù)中,各種函數(shù)名中帶有`create\copy\new\retain`等字眼帚桩,都需要在不需要使用這個(gè)數(shù)據(jù)的時(shí)候進(jìn)行`release`亿驾。
`GCD`的數(shù)據(jù)類型在`ARC`的環(huán)境下不需要再做`release`。
`CF(core Foundation)`的數(shù)據(jù)類型在`ARC`環(huán)境下還是需要做`release`账嚎。 
異步函數(shù)具備開線程的能力莫瞬,但不一定會(huì)開線程。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末郭蕉,一起剝皮案震驚了整個(gè)濱河市疼邀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌召锈,老刑警劉巖旁振,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涨岁,居然都是意外死亡拐袜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門卵惦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阻肿,“玉大人,你說我怎么就攤上這事沮尿〈运” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵畜疾,是天一觀的道長赴邻。 經(jīng)常有香客問我,道長啡捶,這世上最難降的妖魔是什么姥敛? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮瞎暑,結(jié)果婚禮上彤敛,老公的妹妹穿的比我還像新娘。我一直安慰自己了赌,他們只是感情好墨榄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著勿她,像睡著了一般袄秩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天之剧,我揣著相機(jī)與錄音郭卫,去河邊找鬼。 笑死背稼,一個(gè)胖子當(dāng)著我的面吹牛贰军,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播雇庙,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼谓形,長吁一口氣:“原來是場噩夢啊……” “哼灶伊!你這毒婦竟也來了疆前?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤聘萨,失蹤者是張志新(化名)和其女友劉穎竹椒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體米辐,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胸完,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翘贮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赊窥。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖狸页,靈堂內(nèi)的尸體忽然破棺而出锨能,到底是詐尸還是另有隱情,我是刑警寧澤芍耘,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布址遇,位于F島的核電站,受9級(jí)特大地震影響斋竞,放射性物質(zhì)發(fā)生泄漏倔约。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一坝初、第九天 我趴在偏房一處隱蔽的房頂上張望浸剩。 院中可真熱鬧,春花似錦鳄袍、人聲如沸绢要。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袖扛。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛆封,已是汗流浹背唇礁。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惨篱,地道東北人盏筐。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像砸讳,于是被迫代替她去往敵國和親琢融。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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