GCD

-GCD中的核心詞是dispatch queue。一個隊列實際上就是一系列的代碼塊巍实,這些代碼可以在主線程或后臺線程中以同步或者異步的方式執(zhí)行画切。一旦隊列創(chuàng)建完成,操作系統(tǒng)就接管了這個隊列撩穿,并將其分配到任意一個核心中進行處理。不管有多少個隊列谒撼,它們都能被系統(tǒng)正確地管理食寡,這些都不需要開發(fā)者進行手動管理。隊列遵循 FIFO 模式(先進先出)廓潜,這意味著先進隊列的任務(wù)會先被執(zhí)行(想像在柜臺前排隊的隊伍抵皱,排在第一個的會首先被服務(wù),排在最后的就會最后被服務(wù))辩蛋。

  • 另一個重要的概念就是WorkItem(任務(wù)項)叨叙。一個任務(wù)項就是一個代碼塊,它可以隨同隊列的創(chuàng)建一起被創(chuàng)建堪澎,也可以被封裝起來擂错,然后在之后的代碼中進行復(fù)用。正如你所想樱蛤,任務(wù)項的代碼就是 dispatch queue 將會執(zhí)行的代碼钮呀。隊列中的任務(wù)項也是遵循 FIFO 模式。這些執(zhí)行可以是同步的昨凡,也可以是異步的爽醋。對于同步的情況下,應(yīng)用會一直堵塞當前線程便脊,直到這段代碼執(zhí)行完成蚂四。而當異步執(zhí)行的時候,應(yīng)用先執(zhí)行任務(wù)項哪痰,不等待執(zhí)行結(jié)束遂赠,立即返回。
  • 在為主隊列添加任務(wù)時晌杰,無論何時都要加倍小心跷睦。這個隊列要隨時用于界面響應(yīng)以及用戶交互。并且記住一點肋演,所有與用戶界面相關(guān)的更新都必須在主線程執(zhí)行抑诸。如果你嘗試在后臺線程更新 UI烂琴,系統(tǒng)并不保證這個更新何時會發(fā)生,大多數(shù)情況下蜕乡,這會都用戶帶來不好的體驗奸绷。但是,所有發(fā)生在界面更新前的任務(wù)都可以在后臺線程執(zhí)行层玲。
  • 我們不一定需要每次都創(chuàng)建自己的隊列号醉。系統(tǒng)維護的全局隊列可以用來執(zhí)行任何我們想執(zhí)行的任務(wù)。至于隊列在哪一個線程運行称簿,iOS 維護了一個線程池,即一系列除主線程之外的線程惰帽,系統(tǒng)會從中挑選一至多條線程來使用(取決于你所創(chuàng)建的隊列的數(shù)據(jù)憨降,以及隊列創(chuàng)建的方式)。哪一條線程會被使用该酗,對于開發(fā)者來說是未知的授药,而是由系統(tǒng)根據(jù)當前的并發(fā)任務(wù),處理器的負載等情況來進行“決定”呜魄。

Dispatch Queue

在 swift 中 dispatch queue 對應(yīng)的類為DispatchQueue 悔叽,可以使用下面方法進行初始化

let queue = (label: String,
  qos: DispatchQoS = default,
  attributes: DispatchQueue.Attributes = default, 
  autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = default,
 target: DispatchQueue? = default)

在 Swift 3 當中,創(chuàng)建一個dispatch queue的最簡單方式:

let queue = DispatchQueue(label: "com.appcode.myqueue")

queue.sync {
      print("同步執(zhí)行")
 }
    queue.async {
      print("異步執(zhí)行")
 }

Quality Of Service (QOS) 和優(yōu)先級

  • 在使用GCDdispatch queue時爵嗅,我們經(jīng)常需要告訴系統(tǒng)娇澎,應(yīng)用程序中的哪些任務(wù)比較重要,需要更高的優(yōu)先級去執(zhí)行睹晒。當然趟庄,由于主隊列總是用來處理 UI 以及界面的響應(yīng),所以在主線程執(zhí)行的任務(wù)永遠都有最高的優(yōu)先級伪很。不管在哪種情況下戚啥,只要告訴系統(tǒng)必要的信息,iOS 就會根據(jù)你的需求安排好隊列的優(yōu)先級以及它們所需要的資源(比如說所需的 CPU 執(zhí)行時間)锉试。雖然所有的任務(wù)最終都會完成猫十,但是,重要的區(qū)別在于哪些任務(wù)更快完成呆盖,哪些任務(wù)完成得更晚拖云。

  • 用于指定任務(wù)重要程度以及優(yōu)先級的信息,在 GCD 中被稱為 Quality of Service (Qos)应又。事實上江兢,Qos 是有幾個特定值的枚舉類型,我們可以根據(jù)需要的優(yōu)先級丁频,使用合適的 Qos 值來初始化隊列杉允。如果沒有指定 Qos邑贴,則隊列會使用默認優(yōu)先級進行初始化。

/// 由低到高 優(yōu)先級
 public static let unspecified: DispatchQoS

 public static let background: DispatchQoS

 public static let utility: DispatchQoS

 public static let `default`: DispatchQoS

 public static let userInitiated: DispatchQoS

 public static let userInteractive: DispatchQoS

并發(fā)隊列


///public static let concurrent: DispatchQueue.Attributes
///public static let initiallyInactive: DispatchQueue.Attributes
///attributes 參數(shù)也可以接受另一個名為 initiallyInactive 的值叔磷。如果使用這個值拢驾,
///任務(wù)不會被自動執(zhí)行,而是需要開發(fā)者手動去觸發(fā)改基。
let anotherQueue = DispatchQueue(label:"com.appcode.anotherQueue", 
qos: .utility, attributes: .concurrent)

  • DispatchQueue 類的 activate() 方法會讓任務(wù)開始執(zhí)行繁疤。注意,這個隊列并沒有被指定為并發(fā)隊列秕狰,因此它們會以串行的方式執(zhí)行稠腊。
let anotherQueue = DispatchQueue(label:"com.appcode.anotherQueue",
 qos: .utility, attributes: .initiallyInactive)
anotherQueue.activate()
  • 現(xiàn)在的問題是,我們?nèi)绾卧谥付?code>initiallyInactive 的同時將隊列指定為并發(fā)隊列鸣哀?其實很簡單架忌,我們可以將兩個值放入一個數(shù)組當中,作為attributes的參數(shù)我衬,替代原本指定的單一數(shù)值叹放。
let anotherQueue = DispatchQueue(label:"com.appcode.anotherQueue", 
qos: .userInitiated, attributes: [.concurrent, .initiallyInactive])

延遲執(zhí)行

let delayQueue = DispatchQueue(label: "com.appcoda.delayqueue", qos: .userInitiated)

print(Date())

let additionalTime: DispatchTimeInterval = .seconds(2)
delayQueue.asyncAfter(deadline: .now() + additionalTime) {
    print(Date())
}

全局隊列和主隊列


let globalQueue = DispatchQueue.global(qos: .userInitiated)

DispatchQueue.main.async {
    // Do something
}

DispatchWorkItem

-DispatchWorkItem 是一個代碼塊,它可以在任意一個隊列上被調(diào)用挠羔,因此它里面的代碼可以在后臺運行井仰,也可以在主線程運行。它的使用真的很簡單破加,就是一堆可以直接調(diào)用的代碼俱恶,而不用像之前一樣每次都寫一個代碼塊。

var value = 10
 let workItem = DispatchWorkItem {
       value += 5
 }
workItem.perform()/// 這行代碼會在主線程上面調(diào)用

///其他隊列執(zhí)行
let queue = DispatchQueue.global()
queue.async {
    workItem.perform()
}

queue.async(execute: workItem)

  • 當一個任務(wù)項被調(diào)用后范舀,你可以通知主隊列(或者任何其它你想要的隊列)
workItem.notify(queue: DispatchQueue.main) {
    print("value = ", value)
}


    var value = 10

    let workItem = DispatchWorkItem {
        value += 5
    }

    workItem.perform()

    let queue = DispatchQueue.global(qos: .utility)

    queue.async(execute: workItem)

    workItem.notify(queue: DispatchQueue.main) {
        print("value = ", value)
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末速那,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子尿背,更是在濱河造成了極大的恐慌端仰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件田藐,死亡現(xiàn)場離奇詭異荔烧,居然都是意外死亡,警方通過查閱死者的電腦和手機汽久,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門鹤竭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人景醇,你說我怎么就攤上這事臀稚。” “怎么了三痰?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵吧寺,是天一觀的道長窜管。 經(jīng)常有香客問我,道長稚机,這世上最難降的妖魔是什么幕帆? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮赖条,結(jié)果婚禮上失乾,老公的妹妹穿的比我還像新娘。我一直安慰自己纬乍,他們只是感情好碱茁,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仿贬,像睡著了一般纽竣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诅蝶,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天退个,我揣著相機與錄音募壕,去河邊找鬼调炬。 笑死,一個胖子當著我的面吹牛舱馅,可吹牛的內(nèi)容都是我干的缰泡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼代嗤,長吁一口氣:“原來是場噩夢啊……” “哼棘钞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起干毅,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宜猜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后硝逢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姨拥,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年渠鸽,在試婚紗的時候發(fā)現(xiàn)自己被綠了叫乌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡徽缚,死狀恐怖憨奸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凿试,我是刑警寧澤排宰,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布似芝,位于F島的核電站,受9級特大地震影響额各,放射性物質(zhì)發(fā)生泄漏国觉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一虾啦、第九天 我趴在偏房一處隱蔽的房頂上張望麻诀。 院中可真熱鬧,春花似錦傲醉、人聲如沸蝇闭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呻引。三九已至,卻和暖如春吐咳,著一層夾襖步出監(jiān)牢的瞬間逻悠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工韭脊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留童谒,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓沪羔,卻偏偏與公主長得像饥伊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蔫饰,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

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

  • GCD(Grand Central Dispatch) 介紹 GCD 屬于系統(tǒng)級的線程管理琅豆,在 Dispatch ...
    fuyoufang閱讀 4,668評論 0 10
  • 盡管 Grand Central Dispatch (GCD)已經(jīng)存在一段時間了,但并非每個人都知道怎么使用它篓吁。這...
    coderFamer閱讀 7,399評論 1 16
  • 基于自 raywenderlich.com 在2015年的兩篇文章 Grand Central Dispatch ...
    seedante閱讀 1,371評論 0 7
  • 一茫因、本周計劃(一)這周就要跑馬,周二進行半馬練習(xí)杖剪,每天拿出時間規(guī)劃準備冻押;(二)幸福雙翼跟上進程,錄制音頻摘盆;翼雀、(三)...
    舜間永恒閱讀 153評論 0 1
  • 很久沒有遛彎了。 最近心情總是起起落落孩擂,心里那股子叛逆也上來了狼渊。 對啊,我就是不想考好,不想去迎合應(yīng)試教育狈邑。 我呸...
    花房姑娘__閱讀 221評論 0 0