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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/531537.html
標籤:iOS
