Swift多線程開發(fā) - 2. GCD 隊列和線程

一個App是 一個進(jìn)程微饥,一個進(jìn)程擁有 多個線程颅眶。GCD隊列負(fù)責(zé)分配任務(wù)到不同的線程上都哭。

多線程的優(yōu)點:

  • 運行更快. 多線程可以并發(fā)處理任務(wù)啊易,速度比串行更快
  • 響應(yīng). 如果全部任務(wù)都在主線程進(jìn)行吁伺,那么在出現(xiàn)比較耗時的任務(wù)的時候,用戶會明顯感覺到卡頓造成較差的用戶體驗租谈。
  • 優(yōu)化的資源消耗. 多線程經(jīng)過操作系統(tǒng)高度優(yōu)化的篮奄,使得線程切換等消耗極小。

1. 基礎(chǔ)應(yīng)用

串行

 let label = "wang.junshuo.example"
 let queue = DispatchQueue(label: label)

并發(fā)

 let label = "wang.junshuo.example"
 let queue = DispatchQueue(label: label, attributes: .concurrent)

在推薦的規(guī)范中垦垂,label的命名采用BundleID似的反域名的方式加上功能名稱,比如com.company.app

主隊列

應(yīng)用啟動的時候會自動創(chuàng)建負(fù)責(zé)用戶界面的 串行 主隊列宦搬。
由于使用頻率很高,它可以方便的通過DispatchQueue.main類變量訪問劫拗。

2. 優(yōu)先級(Quality of service)

不同重要程度的任務(wù)通過QoS可以使用不同程度的系統(tǒng)資源和電量间校,達(dá)到高效完成

比如取一個.userInteractive級別的全局隊列
let queue = DispatchQueue.global(qos: .userInteractive)

級別

系統(tǒng)預(yù)設(shè)的優(yōu)先級有六個。

a. .userInteractive

這個級別的任務(wù)設(shè)計為處理直接與用戶交互相關(guān)的任務(wù)页慷。比如界面更新計算憔足,動畫等。
如果這個任務(wù)不馬上完成酒繁,用戶界面看起來就會卡住滓彰。所以提交到這個隊列任務(wù)需要立即完成.

b. .userInitiated

這個級別的任務(wù)設(shè)計為處理需要立即發(fā)生但是可以異步完成。比如從用戶點擊查看一個文檔州袒,或者從本地數(shù)據(jù)庫讀取信息等揭绑。
這里的任務(wù)也期望短時間或幾秒內(nèi)迅速完成。

c. .default

這個選項是默認(rèn)值郎哭,是作為沒有明確設(shè)定優(yōu)先級的時候的缺省值他匪。最好給每個任務(wù)都設(shè)定一個級別而不是使用這個值。

c. .utility

這個級別的任務(wù)設(shè)計為用于長時間運行的計算等夸研。比如聯(lián)網(wǎng)或連續(xù)數(shù)據(jù)饋送邦蜜。
任務(wù)會在響應(yīng)速度和性能與能源效率之間取得平衡。這里的任務(wù)可能需要幾秒鐘到幾分鐘亥至。

d. .background

這個級別的任務(wù)設(shè)計為用于花費長時間并且用戶不在乎它什么時候完成的悼沈。比如數(shù)據(jù)庫維護(hù),同步遠(yuǎn)程服務(wù)器和備份姐扮。
這里的任務(wù)將專注于能源效率而不是速度絮供,那些用大量時間(幾分鐘或更長)的工作應(yīng)該放這里。

e. .unspecified

這個選項是用于兼容舊版API茶敏,因為有些舊版API可能會使線程超出QoS范圍杯缺。所以不要使用這個值。

優(yōu)先級推斷

如果加入隊列的任務(wù)優(yōu)先級比隊列高睡榆,那么隊列中以及其包含的所有任務(wù)的優(yōu)先級也會自動提升到這個優(yōu)先級萍肆。

3. 添加任務(wù)

比如添加一個網(wǎng)路請求任務(wù)然后刷新

DispatchQueue.global(qos: .utility).async { [weak self] in
    guard let self = self else { return }
    // 網(wǎng)絡(luò)請求代碼

    // 切換到主線程刷新任務(wù)
    DispatchQueue.main.async {
        self.textLabel.text = "JuHub又更新了哇!" 
    }
}

注意點

上述代碼有兩點值得注意

a. Weak Self

GCD是不會造成循環(huán)引用的胀屿, 但是在GCD的閉包中強(qiáng)引用self會使得self更晚被釋放(直到網(wǎng)絡(luò)請求完成才會釋放)塘揣。
比如在一個將要被dismissviewController中網(wǎng)絡(luò)請求還沒有完成,則弱引用selfviewController會被直接釋放(如果沒有其它循環(huán)引用)宿崭,而強(qiáng)引用的viewController直到網(wǎng)絡(luò)請求完成才會釋放亲铡。

具體要不要弱引用self完全取決于業(yè)務(wù)需求

b. 主線程刷新

通常我們都是在網(wǎng)絡(luò)請求完之后異步刷新主線程。使用sync要非常注意葡兑,因為一旦錯誤的調(diào)用比如在當(dāng)前線程同步任務(wù)中訪問同步隊列中的資源奖蔓,那么當(dāng)前線程就會造成死鎖問題。

在主線程添加同步任務(wù)會造成主線程死鎖

更進(jìn)一步的讹堤,在上一篇中我們講過無法確定隊列中的任務(wù)最終會被分配到哪個線程吆鹤,所以在你創(chuàng)建了一個自定義隊列然后添加同步任務(wù)的時候,這個同步任務(wù)可能還是在主線程執(zhí)行洲守。而此時如果在這個自定義隊列里DispatchQueue.main.sync(){}就會造成死鎖

func test() {
    let queue = DispatchQueue(label: "wang.junshuo.example.testQueue")

    print("1\(Thread.current)") // Main Thread

    queue.sync {
        print("2\(Thread.current)") // Main Thread 
        DispatchQueue.main.sync {
            print("3\(Thread.current)") // Main Thread. 死鎖
        }
    }
}

所以執(zhí)行同步任務(wù)的時候要十二分的謹(jǐn)慎疑务。



作者博客地址

系列文章鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市梗醇,隨后出現(xiàn)的幾起案子知允,更是在濱河造成了極大的恐慌,老刑警劉巖叙谨,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件温鸽,死亡現(xiàn)場離奇詭異,居然都是意外死亡手负,警方通過查閱死者的電腦和手機(jī)涤垫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虫溜,“玉大人雹姊,你說我怎么就攤上這事『饫悖” “怎么了吱雏?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瘾境。 經(jīng)常有香客問我歧杏,道長,這世上最難降的妖魔是什么迷守? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任犬绒,我火速辦了婚禮,結(jié)果婚禮上兑凿,老公的妹妹穿的比我還像新娘凯力。我一直安慰自己茵瘾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布咐鹤。 她就那樣靜靜地躺著拗秘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祈惶。 梳的紋絲不亂的頭發(fā)上雕旨,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音捧请,去河邊找鬼凡涩。 笑死,一個胖子當(dāng)著我的面吹牛疹蛉,可吹牛的內(nèi)容都是我干的活箕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氧吐,長吁一口氣:“原來是場噩夢啊……” “哼讹蘑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起筑舅,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤座慰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后翠拣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體版仔,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年误墓,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛮粮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡谜慌,死狀恐怖然想,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情欣范,我是刑警寧澤变泄,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站恼琼,受9級特大地震影響妨蛹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晴竞,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一蛙卤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦颤难、人聲如沸神年。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘤袖。三九已至,卻和暖如春昂验,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艾扮。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工既琴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泡嘴。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓甫恩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酌予。 傳聞我的和親對象是個殘疾皇子磺箕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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