分析問(wèn)題前現(xiàn)需要明白原理,了解清楚本質(zhì)才能分析透徹资厉。
1演顾、首先我們要明白什么是GCD
Grand Central Dispatch (GCD) 是異步執(zhí)行任務(wù)技術(shù)之一疟赊。會(huì)自動(dòng)的根據(jù)CPU的使用情況孤荣,創(chuàng)建線程來(lái)執(zhí)行任務(wù)甸陌,并且自動(dòng)的運(yùn)行到多核上,提高程序的運(yùn)行效率盐股。對(duì)于開發(fā)者來(lái)說(shuō)钱豁,在GCD層面是沒(méi)有線程的概念的,只有隊(duì)列(queue)疯汁,任務(wù)都是以block的方式提交到對(duì)列上寥院,然后GCD會(huì)自動(dòng)的創(chuàng)建線程池去執(zhí)行這些任務(wù)。
GCD 的核心:隊(duì)列 涛目、任務(wù) 、追加任務(wù)的方法
1.1 凛澎、DispatchQueue(任務(wù)隊(duì)列)
執(zhí)行任務(wù)的等待隊(duì)列霹肝,按照追加順序先進(jìn)先出(FIFO)執(zhí)行處理。
隊(duì)列的兩種類型:Serial Dispatch Queue 和 Concurrent Dispatch Queue
1.2 塑煎、任務(wù)
使用閉包‘’定義執(zhí)行的任務(wù)‘’
// 創(chuàng)建串行隊(duì)列
let serialQueue = DispatchQueue.init(label: "com.start")
serialQueue.async {
print("異步追加任務(wù)")
}
1.3 沫换、追加任務(wù)的方法
通過(guò)同步(sync)和異步(async)方法追加任務(wù)到隊(duì)列
- async是將指定的任務(wù)非同步的追加到指定的Dispatch Queue,不做任何等待最铁。
- sync是將指定的任務(wù)追加到指定的Dispatch Queue讯赏,在追加任務(wù)執(zhí)行結(jié)束前,一直等待(意味著當(dāng)前線程停止冷尉,等待追加任務(wù)執(zhí)行結(jié)束后繼續(xù)執(zhí)行)漱挎。
2、場(chǎng)景分析
2.1異步追加任務(wù)嵌套同步追加任務(wù)導(dǎo)致線程鎖死
func dispatchSerialQueue1(){
print(Thread.current)
// 創(chuàng)建串行隊(duì)列
let serialQueue = DispatchQueue.init(label: "com.start")
// 主線程打印: 1
print("1")
// 串行隊(duì)列異步添加任務(wù) (當(dāng)前線程繼續(xù)執(zhí)行)
serialQueue.async {
print(Thread.current)
// 串行隊(duì)列創(chuàng)建的線程執(zhí)行打印: 2
print("2")
// 串行隊(duì)列同步添加任務(wù) (當(dāng)前線程暫停 等待添加的任務(wù)執(zhí)行完)
serialQueue.sync {
print("3")
}
print("4")
}
// 主線程打印: 5
print("5")
}
分析:
1.主線程內(nèi)創(chuàng)建串行任務(wù)隊(duì)列
2.串行隊(duì)列異步添加任務(wù)雀哨,主線程不需要等待繼續(xù)執(zhí)行磕谅,系統(tǒng)創(chuàng)建線程執(zhí)行任務(wù)
3.cpu為任務(wù)隊(duì)列創(chuàng)建的子線程(number = 7),執(zhí)行添加的任務(wù)
4.任務(wù)內(nèi)部同步添加新任務(wù)雾棺,導(dǎo)致當(dāng)前執(zhí)行任務(wù)的子線(number = 7)程暫停
5.同步添加任務(wù)需要等待添加的任務(wù)執(zhí)行結(jié)束膊夹,而新任務(wù)執(zhí)行線程暫停,導(dǎo)致底層上報(bào)錯(cuò)誤奔潰捌浩。