iOS-多線程-GCD

來源:互聯網
上載者:User

標籤:

一. 名詞解釋: 

1. 進程和線程

    進程是指在系統中正在啟動並執行一個應用程式.每個進程之間都是獨立的,每個進程均運行在期專用而且受到保護的記憶體空間中.

    線程是指一個進程想要執行任務,就必須要有線程.線程是進程的基本單元,一個進程的所有任務都線上程中進行.   

2. 具體的對多線程的描述請看 文頂頂大神的部落格.http://www.cnblogs.com/wendingding/p/3805088.html

二. 隊列

/** 隊列: 用於存放任務.分為:串列隊列和並行隊列. 1. 串列隊列: 放到串列隊列中的任務,GCD會FIFO(先進先出)的取出來一個,執行一個,然後取出來下一個,這樣一個一個的執行. 2. 並行隊列: 放到並行隊列中的任務,GCD也會FIFO的取出來,但不同的是,他取出來一個任務就會放到別的線程中,然後取出來一個又放到另一個線程中.由於取的動作很快,可以忽略不計,看起來,所有的任務都是一起執行的.不過需要注意,GCD會根據系統資源控制並行的數量.所以任務很多也不會然所有的任務都執行. */

三. 任務

/** 任務: 有兩種執行方式,同步執行和非同步執行.區別是是否會建立新的線程. 1. 同步執行(sync): 會阻塞當前的線程並等待Block執行完畢,然後當前線程才會繼續往下運行. 2. 非同步執行(async): 當前線程會直接往下執行,它不會阻塞當前線程. */

四.

    /** 擷取主線程     1. 所有的重新整理UI介面的任務都要在主線程執行.     2. 將消耗時間的任務放在別的線程中出來,盡量不要在主線程中處理.     */    dispatch_queue_t main_queue = dispatch_get_main_queue();    NSLog(@"main_queue:\n %@",main_queue);        /** 自己建立的隊列  dispatch_queue_create     參數1: 第一個參數是標識符.用於DEBUG的時候標誌唯一的隊列,可以為空白.     參數2: 第二個參數用來表示建立的隊列是串列的還是並行的.傳入DISPATCH_QUEUE_SERIAL或者NULL表示建立的是串列隊列.傳入DISPATCH_QUEUE_CONCURRENT表示建立的並行隊列. (SERIAL--> serial連續的/CONCURRENT--> concurrent,並發的,一致的)     */        // 建立串列隊列    dispatch_queue_t serialQueue = dispatch_queue_create(nil, NULL);    NSLog(@"serialQueue:\n %@",serialQueue);    // 建立並行隊列: 這應該是唯一一個並行隊列,只要是並行任務一般都加入到這個隊列    dispatch_queue_t concurrentQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);    NSLog(@"concurrentQueue:\n %@",concurrentQueue);            // 建立任務    /** 同步任務 (sync)     1. 不會另外開闢線程.     */    dispatch_sync( serialQueue, ^{               for (int i = 0; i < 10000; i ++)        {            NSLog(@"同步任務: \n%@",[NSThread currentThread]);        }    });        /** 同步任務 (async)     1. 會另外開闢線程.     */    dispatch_async(serialQueue, ^{        NSLog(@"非同步任務: %@",[NSThread currentThread]);    });

五. 例子介紹

NSLog(@"之前==> %@",[NSThread currentThread]);        dispatch_sync(dispatch_get_main_queue(), ^{                NSLog(@"sync==> %@",[NSThread currentThread]);    });        NSLog(@"之後==> %@",[NSThread currentThread]);            /** 解釋     1. 只會列印第一句:之前==> <NSThread: 0x7fe66b700610>{number = 1, name = main} ,然後主線程就卡死了,你可以在介面上放一個按鈕,你就會發現點不了了。     2. 列印完第一句,dispatch_sync(因為是一個同步任務,會阻塞當前的線程)會阻塞當前的主線程,然後把Block中的任務放到main_queue中,main_queue中的任務會被取出來放到主線程中執行,但主線程種鴿時候已經被阻塞了,所以Block種鴿的任務就不能完成,它不完成,dispatch_sync就會一直阻塞主線程.導致主線程一直卡死.這就是死結現象.     */
 dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);        NSLog(@"輸出1.之前==> %@",[NSThread currentThread]);        dispatch_async(queue, ^{                NSLog(@"輸出2.sync之前==> %@",[NSThread currentThread]);                dispatch_sync(queue, ^{                        NSLog(@"輸出3.sync==> %@",[NSThread currentThread]);        });        NSLog(@"輸出4.sync之後==> %@",[NSThread currentThread]);    });        NSLog(@"輸出5.之後==> %@",[NSThread currentThread]);        /** 解釋     1. 當前線程為預設的主線程     2. 輸出結果為,輸出1,輸出5和輸出2 執行了輸出.輸出3和輸出4沒有被執行.     3. 按照執行順序分析.        (1)我們建立的隊列queue是一個串列隊列(DISPATCH_QUEUE_SERIAL).串列隊列的特點是,所持有的任務會取出一個執行一個.當前任務沒有執行完,下一個任務不會被執行.        (2)列印出輸出1.        (3)在queue隊列中開啟了一個非同步任務(async).非同步任務的特點是,當前的線程不會被阻塞.所以有了兩條線程,一條是主線程中執行輸出5.另一條是在新開闢的queue線程中執行輸出2.        (4)在開闢的queue線程中,又執行了一個同步的任務(sync),同步任務的特點是執行一個任務會阻塞當前的線程.當前的線程是queue,已經被阻塞了.又要求它去執行下一個任務.就造成了死結現象.所以 sync 所在的線程被卡死了,輸出3和輸出4自然就不會列印了.     */

六.隊列組可以將很多隊列添加到一個組裡,這樣做的好處是,當這個組裡所有的任務都執行完了,隊列組會通過一個方法通知我們。

    //1. 建立隊列組    dispatch_group_t group = dispatch_group_create();        //2. 建立隊列  dispatch_get_global_queue 會擷取一個全域隊列,我們姑且理解為系統為我們開啟的一些全域線程。我們用priority指定隊列的優先順序,而flag作為保留欄位備用(一般為0)。    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);        //3. 多次使用隊列中的方法執行任務,只有非同步任務    //3.1 執行三次迴圈    dispatch_group_async(group, queue, ^{               for (int i = 0; i < 3; i ++)        {            NSLog(@"group-01 - %@",[NSThread currentThread]);        }    });        //3.2 主隊列執行8次迴圈    dispatch_group_async(group, dispatch_get_main_queue(), ^{               for (int i = 0; i < 8; i ++)        {            NSLog(@"group-02 - %@",[NSThread currentThread]);        }    });        //3.3 執行5次迴圈    dispatch_group_async(group, queue, ^{                for (int i = 0; i < 5; i ++)        {            NSLog(@"group-03 - %@",[NSThread currentThread]);        }    });        dispatch_group_notify(group, dispatch_get_main_queue(), ^{               NSLog(@"完成 - %@",[NSThread currentThread]);    });

 

iOS-多線程-GCD

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.