1. 程式人生 > >GCD常見的死鎖問題之一

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”)執行完畢,所以就卡死在這了。