1. 程式人生 > >iOS中主佇列的同/非同步執行

iOS中主佇列的同/非同步執行

主佇列是主線中的一個序列佇列,通常我們重新整理UI都會回到主佇列。下面我們來看一下主佇列同步執行和非同步執行會產生什麼樣的效果。

主佇列,非同步執行

//主佇列+非同步執行
//不會開啟新的執行緒,任務順序執行
-(void)test5{
    NSLog(@"主佇列+非同步執行");
    //global_queue 主佇列
    dispatch_queue_t queue = dispatch_get_main_queue();
    //dispatch_async 非同步執行
    dispatch_async(queue, ^{
        for (int i = 0
; i < 10; i ++) { NSLog(@"1------%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 10; i ++) { NSLog(@"2------%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 10
; i ++) { NSLog(@"3------%@",[NSThread currentThread]); } }); NSLog(@"end"); }

列印結果:

2018-08-30 13:13:04.267741+0800 GCD_demo[2846:151142] 主佇列+非同步執行
2018-08-30 13:13:04.267853+0800 GCD_demo[2846:151142] end
2018-08-30 13:13:04.270849+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main}
2018-08-30 13:13:04.270981+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.271349+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.271499+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.271774+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.271930+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.272077+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.272461+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.272559+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.272959+0800 GCD_demo[2846:151142] 1------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.273210+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.273323+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.273433+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.273799+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.274130+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.274484+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.274732+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.274909+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.275144+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.275409+0800 GCD_demo[2846:151142] 2------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.275707+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.276049+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.276228+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.277371+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.277609+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.277728+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.277858+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.277973+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.278075+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main} 2018-08-30 13:13:04.278478+0800 GCD_demo[2846:151142] 3------<NSThread: 0x604000077540>{number = 1, name = main}

主佇列非同步執行時,會先執行完主執行緒上的程式碼,然後在主執行緒上順序執行任務,不會有新的執行緒產生,所有任務都是在主執行緒上完成的。

主佇列,同步執行

//主佇列+同步執行
//在主執行緒中執行時會死鎖,程式會崩潰
-(void)test6{
    //死鎖原因:同步對於任務是立刻執行的,當把第一個任務放進主佇列時,就會立即執行。可是主執行緒現在正在處理test6方法,任務需要等test6執行完才能執行,然後任務不執行完的話,test6方法也不算執行完,所以出現了test6需要等待任務執行完才能執行完,而任務又需要等待test6執行完才能執行。相互等待,死鎖!
    NSLog(@"主佇列+同步執行");
    //global_queue 主佇列
    dispatch_queue_t queue = dispatch_get_main_queue();
    //dispatch_async 同步執行
    //任務
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"1------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"2------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"3------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"end");
}

以上方法直接在主執行緒中呼叫的話會造成死鎖,可以放到子執行緒中去執行,如使用如下方法呼叫:

dispatch_async(dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL), ^{
        [self test6];
    });

列印結果:

2018-08-30 13:23:52.827501+0800 GCD_demo[2975:159890] 主佇列+同步執行
2018-08-30 13:23:52.830572+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.830986+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.831360+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.831610+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.831685+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.831847+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.831954+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.832051+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.832248+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.832477+0800 GCD_demo[2975:159805] 1------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.833122+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.833498+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.833786+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.834105+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.834322+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.834583+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.834833+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.835076+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.835285+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.835551+0800 GCD_demo[2975:159805] 2------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.836106+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.836188+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.836303+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.836637+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.836775+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.836966+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.837446+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.838085+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.838172+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.838279+0800 GCD_demo[2975:159805] 3------<NSThread: 0x60400007f380>{number = 1, name = main}
2018-08-30 13:23:52.838639+0800 GCD_demo[2975:159890] end

放到子執行緒中執行,test6方法中的任務不用等待test6執行完再執行,所以不會死鎖。