筆記整理 之 Block 阻塞主線程 分析

GCD 雖相比NSOpretion 無法提供 取消任務的功能,確因方便而強大廣受喜愛。

但是如此強大的工具用不好可能會出現(xiàn)線程死鎖。 如下代碼:

- (void)viewDidLoad

{

? ? [super viewDidLoad];

? ? NSLog(@"=================4");

? ? dispatch_sync(dispatch_get_main_queue(), ^{

? ? ? ? NSLog(@"=================5");

? ? });

? ? NSLog(@"=================6");

}

GCD Queue 分為三種:

1,The main queue? :主隊列,主線程就是在個隊列中。

2,Global queues : 全局并發(fā)隊列。

3,用戶隊列:是用函數(shù) dispatch_queue_create 創(chuàng)建的自定義隊列

dispatch_sync 和? dispatch_async 區(qū)別:

dispatch_async(queue,block)? async 異步執(zhí)行,dispatch_async 函數(shù)會立即返回, block會在后臺異步執(zhí)行。

dispatch_sync(queue,block)? sync 同步分發(fā),順序執(zhí)行,dispatch_sync 函數(shù)不會立即返回,插入到當前線程,等待 block同步執(zhí)行完成。

分析上面代碼:

viewDidLoad 在主線程中, 已在

dispatch_get_main_queue() 中,執(zhí)行到sync 時 向

dispatch_get_main_queue()插入 同步 threed1還是主線程.


sync 會等到 其block 執(zhí)行完成才返回并執(zhí)行后面的代碼, sync 又在 dispatch_get_main_queue() 隊列中的viewdidload中,在串形隊列中,sync 在上一個函數(shù)還沒執(zhí)行完時插入,形成在主線程有兩個互相等待執(zhí)行結束的情況,

sync 想執(zhí)行 block 必須等待主線程中的上一個任務didload執(zhí)行完成,而didload 必須等待 sync 執(zhí)行block返回才能去執(zhí)行后續(xù)代碼。


造成死鎖,sync 等待mainThread 執(zhí)行完成, mianThread 等待sync 函數(shù)返回。


下面例子:

- (void)viewDidLoad

{

? ? [super viewDidLoad];


? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ?

? ? NSLog(@"=================1");

? ?

? ? dispatch_sync(dispatch_get_main_queue(), ^{

? ? ? ? NSLog(@"=================2");


? ? });

? ? NSLog(@"=================3");


? ?

});


}

程序會完成執(zhí)行,為什么不會出現(xiàn)死鎖。

首先: async 在主線程中? 創(chuàng)建了一個異步線程 加入? 全局并發(fā)隊列,async 不會等待block 執(zhí)行完成,立即返回,

1,async 立即返回,并在子線程執(zhí)行其block 打印1,到碰到sync main判斷主線程在執(zhí)行任務,若有就等等,也可能是一直等。當viewDidLoad 順序執(zhí)行后續(xù)代碼并從主線程中清除,然后sync main block執(zhí)行。打印2,之后再打印3

2,同時,全局并發(fā)隊列立即執(zhí)行異步 block , 打印 1, 當執(zhí)行到 sync 它會等待 block 執(zhí)行完成才返回, 及等待

dispatch_get_main_queue() 隊列中的 mianThread 執(zhí)行完成, 然后才開始調(diào)用block 。


因為1 和 2 幾乎同時執(zhí)行,因為2 在全局并發(fā)隊列上, 2 中執(zhí)行到sync 時 1 可能已經(jīng)執(zhí)行完成或 等了一會。


如果阻塞了主線程,2 中的sync 就無法執(zhí)行啦,mainThread 永遠不會退出, sync 就永遠等待著,

- (void)viewDidLoad

{

? ? [super viewDidLoad];

dispatch_async(dispatch_get_global_queue(0, 0), ^{

? ? NSLog(@"=================1");

? ? dispatch_sync(dispatch_get_main_queue(), ^{

? ? ? ? NSLog(@"=================2");

? ? });

? ? NSLog(@"=================3");

});

? ? NSLog(@"==========阻塞主線程");

? ? while (1) {

? ? }

? ? NSLog(@"========2==阻塞主線程");


}

打印如下:

2014-11-30 17:56:22.296 Test[6108:379350] =================1

2014-11-30 17:56:22.296 Test[6108:379231] ==========阻塞主線程。

簡單理解主線程,和任務的同/異步分發(fā)。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容