GCD使用小結(jié)

GCD是iOS開發(fā)過程當(dāng)中使用的比較頻繁也比較重要的一塊,往往項(xiàng)目里涉及到這方面的代碼基本都是核心功能,維護(hù)的時(shí)候都小心翼翼,如果這里出問題給調(diào)試帶來的難度是較大的。

下面我就來回顧溫習(xí)一下GCD有關(guān)知識(shí),如有紕漏和不足,歡迎指正。

本文主要通過一下幾個(gè)模塊來進(jìn)行總結(jié):

(1)多線程概念;

(2)幾種多線程編程的優(yōu)缺點(diǎn);

(3) GCD中的幾種隊(duì)列類型;

(4)GCD中系統(tǒng)提供的常用dispatch方法;

多線程相關(guān)概念

1. 線程與進(jìn)程:

進(jìn)程:是指程序在計(jì)算機(jī)上的一次執(zhí)行過程,例如開啟微信,就是開啟了一個(gè)進(jìn)程,進(jìn)程可包含多個(gè)線程。

線程:一組獨(dú)立執(zhí)行的代碼段,一個(gè)線程同時(shí)只能執(zhí)行一個(gè)任務(wù),故而多線程并發(fā)就是指在同一時(shí)間執(zhí)行多個(gè)任務(wù)。

iOS程序中,主線程(又稱為UI線程)主要任務(wù)就是顯示和刷新UI,也只有主線程可以直接修改UI,其他耗時(shí)操作會(huì)放在子線程(又稱為異步線程)處理,這樣可以提高程序的執(zhí)行效率,提高資源的利用率。

主線程的堆棧大小是1M,其他線程開都是512KB,而且這個(gè)值不可更改,這也就意味著只要開啟一個(gè)線程就會(huì)占用一部分內(nèi)存,線程越多程序的性能也隨之降低,所以一般不建議同時(shí)開啟多個(gè)線程。

2. 線程按照?qǐng)?zhí)行方式又可細(xì)分:

同步線程:同步線程會(huì)阻塞當(dāng)前線程然后開始執(zhí)行該線程內(nèi)的任務(wù),任務(wù)執(zhí)行完之后才會(huì)返回當(dāng)前線程;

異步線程:異步線程不會(huì)阻塞當(dāng)前線程,會(huì)開啟其他線程去執(zhí)行線程內(nèi)的任務(wù);

這里來說下串行和并發(fā)的概念:

串行隊(duì)列:任務(wù)按先后順序逐個(gè)執(zhí)行,需要等待前一個(gè)任務(wù)執(zhí)行完之后才開始執(zhí)行下一個(gè)任務(wù);

并發(fā)隊(duì)列:多個(gè)任務(wù)按先后順序一起開始執(zhí)行,不用等待前一個(gè)任務(wù)執(zhí)行完就可以執(zhí)行下一個(gè)任務(wù),因?yàn)槿蝿?wù)添加的先后順序間隔往往忽略不計(jì),所以看起來像是一起執(zhí)行的。

并發(fā)和并行也是兩個(gè)不同的概念:并行是基于多核設(shè)備的,并行一定是并發(fā),而并發(fā)不一定是并行。

3. 多線程編程中會(huì)經(jīng)常遇到的問題:

死鎖:兩個(gè)或多個(gè)線程都在等待對(duì)方完成某個(gè)操作才能進(jìn)行下一步操作,這時(shí)候就會(huì)發(fā)生死鎖;

互斥鎖:能夠防止多線程搶奪資源造成的數(shù)據(jù)安全問題,但是需要消耗大量的資源;

原子屬性(atomic)加鎖:當(dāng)屬性以atomic修飾時(shí),該屬性就能支持互斥鎖了,反之若以nonatomic修飾,表示忽略了線程安全;

上下文切換:當(dāng)一個(gè)進(jìn)程中有多個(gè)線程來回切換時(shí),content switch用來記錄執(zhí)行狀態(tài),這是就會(huì)產(chǎn)生一些額外的開銷。

幾種多線程編程的優(yōu)缺點(diǎn)

1. NSThread

優(yōu)點(diǎn):輕量級(jí)簡(jiǎn)單易用,可以直接操作線程對(duì)象;

缺點(diǎn):需要自己管理線程的生命周期,線程同步;

2. NSOperation

優(yōu)點(diǎn):基于GCD對(duì)GCD的封裝,比GCD更加面向?qū)ο?,不需要關(guān)心線程管理;

缺點(diǎn):使用時(shí)必須使用它的子類;

3. GCD

優(yōu)點(diǎn):基于C語言更底層更高效,并且不屬于cocoa框架,簡(jiǎn)單易用,效率高,速度快,自動(dòng)管理線程生命周期;

缺點(diǎn):如果遇到較復(fù)雜的使用場(chǎng)景,很大可能會(huì)遇到死鎖問題;

GCD中的幾種隊(duì)列類型

Dispatch block的執(zhí)行最終都會(huì)放進(jìn)某個(gè)隊(duì)列中去執(zhí)行,GCD中相關(guān)函數(shù)的創(chuàng)建一般都以dispatch開頭:

(1)Mainqueue主線程串行隊(duì)列:通過dispatch_get_main_queue來獲取;

(2)Global queue 全局并發(fā)隊(duì)列:通過dispatch_get_global_queue來獲取,可以設(shè)置優(yōu)先級(jí);

(3)Custom queue 自定義隊(duì)列:通過dispatch_queue_create來獲取;

(4)Groupqueue 組隊(duì)列:通過dispatch_group_create來獲?。?/p>

GCD中系統(tǒng)提供的常用dispatch方法

1. Dispatch_after 延時(shí)添加到隊(duì)列;

示例如下:

Dispatch_after

從打印信息來看Dispatch_after只是延時(shí)提交block,并沒有延時(shí)后立即執(zhí)行block,因此它不能實(shí)現(xiàn)精確控制。

2. Diapatch_apply :在給定的隊(duì)列上多次執(zhí)行某一任務(wù),在主線程直接調(diào)用會(huì)阻塞主線程去執(zhí)行block中的任務(wù),所以一般把它放在異步隊(duì)列中執(zhí)行

示例如下:

Diapatch_apply

3. Dispatch_once:保證在app運(yùn)行期間,block中的代碼只執(zhí)行一次

比如一個(gè)經(jīng)典的使用場(chǎng)景:?jiǎn)卫?/p>

Dispatch_once

4. Dispatch_barrier_async :柵欄作用

在并發(fā)隊(duì)列中,等待在Dispatch_barrier之前加入的隊(duì)列全部執(zhí)行完,再執(zhí)行Dispatch_barrier中的任務(wù),執(zhí)行完之后再開始執(zhí)行Dispatch_barrier之后加入到隊(duì)列的任務(wù)。

示例如下:

Dispatch_barrier_async
最后編輯于
?著作權(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)容