dispatch_sync執行了兩件事:把代碼塊放入指定線程的任務隊列中、堵塞當前線程直到代碼塊執行結束,如果出現了堵塞的線程和代碼塊所在的線程為同一線程的話,這個時候代碼無法在此線程執行繼續下去,即造成了死鎖。 - (void)viewDidLoad { [super viewDidLoad]; ...
dispatch_sync執行了兩件事:把代碼塊放入指定線程的任務隊列中、堵塞當前線程直到代碼塊執行結束,如果出現了堵塞的線程和代碼塊所在的線程為同一線程的話,這個時候代碼無法在此線程執行繼續下去,即造成了死鎖。
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_sync(dispatch_get_main_queue(), ^{
//這裡在等B處代碼執行結束再執行
NSLog(@"MrYu4");
});
//B:等代碼塊執行結束再執行
}
額外挑戰
下麵代碼中是否出現死鎖?
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t myQueue = dispatch_queue_create("com.MrYu4.queue", 0);
dispatch_sync(myQueue, ^{
dispatch_sync(dispatch_get_main_queue(), ^{
[self updateLabelWhenBackgroundDone];
});
});
}
解析
如下麵註釋所示,C處、D處代碼永遠不可能執行到,換個理解方式,也可以說myQueue要執行結束需要等待主線程執行完畢,但主線程執行又要等待myQueue執行完畢。
如何理解粗體字?實際上死鎖發生的時候主線程順序上有兩個代碼塊:Z和B,在Z中出現的dispatch_sync(myQueue...堵塞了Z往下接著執行,更別提接著往下執行到B了(主線程是串列線程)
- (void)viewDidLoad {
//Z:主線程中的代碼塊
[super viewDidLoad];
dispatch_queue_t myQueue = dispatch_queue_create("com.MrYu4.queue", 0);
dispatch_sync(myQueue, ^{//A:堵塞當前線程(主線程),將代碼塊放入myQueue線程的任務隊列中
dispatch_sync(dispatch_get_main_queue(), ^{//B:堵塞當前線程(myQueue),講代碼塊放入主線程的任務隊列中
NSLog(@"MrYu4");
});
//C:等待B代碼塊執行結束再執行
});
//D:等待A代碼塊執行結束再執行
}
本文來自博客園,作者:MrYu4,轉載請註明原文鏈接:https://www.cnblogs.com/MrYU4/p/yi-ju-hua-shuoiosdispatch-ru-he-zao-cheng-si-suo.html