GCD常見的死鎖問題之一
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"1");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}
問:列印的結果是什麼?
結果:1,因為執行到這個同步執行緒這裡就死鎖了;
結果:1,3,2 ;因為dispatch_async()被放到了主佇列的末尾執行,即結束了viewDidLoad 主佇列中的內容才執行這個;
首先,無論是同步sync還是非同步async 都是呼叫一個block,這個block會被放到指定的佇列(queue)的隊尾等待執行;至於block中是並行執行還是序列執行那就和dispatch_sync中的引數指定的queue是並行還是序列有關;不同的是sync地等到block有結果了才能進行下一步操作也就是nslog(@"3");而async不需要,可以和nslog(@"3")同時執行;
同步(sync) 操作,它會阻塞當前執行緒並等待 Block 中的任務執行完畢,然後當前執行緒才會繼續往下執行;
非同步(async)操作,它不會阻塞當前的執行緒,會一起執行任務;
viewDidLoad操作是由上到下一步一步往下執行的,dispatch_sync提交一個列印任務NSLog(@”2”)到主執行緒關聯的序列佇列中,主執行緒關聯的序列佇列現在有一個viewDidLoad任務,列印任務NSLog(@”2”)排在viewDidLoad後面,佇列FIFO(先進先出)的原則,列印任務NSLog(@”2”);想要得到執行必須等到viewDidLoad執行完畢後才能得到執行,但是viewDidLoad想要執行完畢必須要等列印任務NSLog(@”2”)執行完畢,所以就卡死在這了。