iOS_多線程_GCD,ios多線程_gcd
1、GCD串列隊列+非同步dispatch說明:非常非常非常有用的操作非同步,表示會在主線程之外開新的線程,但由於 隊列是串列的,故只開一個(只開一個)新的線程當dispatch指派好block之後,主線程立即返回,繼續向下執行串列隊列,表示:被指派到此隊列的block們,將FIFO有序地一個接一個執行dispatch_async說明:立即返回,從不等待,隊列決定是serially還是concurrently,block_copy(),block_release()
程式運行結果輸出:可以看到:串列隊列+非同步方式向隊列添加block,只會新開一個線程,所有被添加的block在新開的線程裡,愉快而有序地執行
2、GCD串列隊列+同步dispatch (極少使用)同步表示:不會開新線程,就在主線程上運行串列表示:所有block一個接一個運行
3、並行隊列+非同步dispatch(容易失控)
開多條新線程(具體開幾個無法控制),block執行沒有順序,程式員無法控制執行順序
4、並發隊列+同步dispatch
關鍵:因為同步,則不會開新線程,直接使用主線程,
雖然是並發隊列,但由於可有一個執行路線,所以會順序執行
5、發散思維--->串列隊列先同步dispatch十個block,再非同步dispatch十個block既然是同步指派:就是在主線程上執行,完畢後,再非同步指派:開新線程,由於隊列是串列,故,只會開一條新線程,一個接一個愉快地執行
6、發散思維--->並行隊列中,先同步指派10個block,再非同步指派10個blcok只要是同步dispatch,就只會在主線程上運行再非同步指派,就一定會開新線程,由於是並行隊列:故會開N條新線程,N數量不可控制,block們的執行順序也不可控制
7、發散思維--->並行隊列中,先非同步指派10個block,再同步指派10個blcok
由於是並行,且是非同步dispatch:因此會開啟多個線程,並且指派完block後,主線程繼續向下執行,只要是同步的dispatch,只會在主線程上執行,因此N條子線程和主線程穿插執行
8、系統提供的全域隊列,供所有的app使用,與【並行隊列】的異同如下:
供所有app使用的全域隊列
全域隊列與並行隊列的3點區別:
1、全域隊列不需create、只要get就可以得到
2、全域隊列沒有名字,因此,調試時,不方便查看
3、全域隊列與並行隊列的執行效果完全相同
9、主隊列 + 同步dispatch 【阻塞死】由於主隊列 一直在、隨時在等待使用者的輸入,因此主隊列,一直在運行,不會退出;一旦退出,程式就結束了;因此,在主隊列裡面 同步指派一個block,是永遠也不會被執行到的,該block會將主線程 阻塞住,該block後面的代碼也永遠不會被執行到
10、主隊列 + async指派在主隊列中,無論如何dispatch,只要是加入到主隊列的block,統一由主隊列進行安排,順序執行
//// ViewController.m// GCD//// Created by xss on 14-11-23.// Copyright (c) 2014年 beyond. All rights reserved.//#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // [self gcd_serial_async]; // [self gcd_serial_sync];// [self gcd_concurrent_async];// [self gcd_concurrent_sync];// [self gcd_concurrent_sync_async];// [self gcd_concurrent_async_sync];// [self gcd_serial_sync_async];// [self gcd_global_queue];// [self gcd_main_queue_sync]; [self gcd_main_queue_async];}/* 1、主隊列 + 非同步dispatch (無論如何dispatch,只要加入主隊列,都將串列執行,統一由主隊列順序安排) */- (void)gcd_main_queue_async{ dispatch_queue_t mainQueue = dispatch_get_main_queue(); // 快速向 主隊列 裡面非同步添加10個block for (int i = 0; i<10; i++) { dispatch_async(mainQueue, ^{ NSLog(@"\n---------->非同步指派:%@--正在執行 主隊列 中的第 %d 個block",[NSThread currentThread],i); }); } }/* 1、主隊列 + 同步dispatch == 永遠不被執行 因為 主隊列 一直有一個block 在監聽並處理 UI操作,一直阻塞,不會退出,不會完結 因此,同步dispatch的,排在其後面的block永遠不會被執行 */- (void)gcd_main_queue_sync{ dispatch_queue_t mainQueue = dispatch_get_main_queue(); NSLog(@"before"); dispatch_sync(mainQueue, ^{ NSLog(@"永遠也不會被執行到"); }); NSLog(@"after");}/* 供所有app使用的全域隊列 全域隊列 與 並行隊列的一點點區別: 1、全域隊列 不需create、只要get就可以得到 2、全域隊列 沒有名字,因此,調試時,不方便查看 3、全域隊列 與並行隊列的執行效果完全相同 */- (void)gcd_global_queue{ dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 快速向隊列裡面同步添加10個block for (int i = 0; i<10; i++) { dispatch_sync(globalQueue, ^{ NSLog(@"\n---------->同步指派:%@--正在執行全域隊列中的第 %d 個block",[NSThread currentThread],i); }); } // 快速向隊列裡面非同步添加10個block for (int i = 0; i<10; i++) { dispatch_async(globalQueue, ^{ NSLog(@"\n---------->非同步指派:%@--正在執行全域隊列中的第 %d 個block",[NSThread currentThread],i); }); }}/* 並行隊列:先非同步指派10個,再同步指派10個 總結:穿插執行 */- (void)gcd_concurrent_async_sync{ dispatch_queue_t queue = dispatch_queue_create("並行隊列", DISPATCH_QUEUE_CONCURRENT); // 快速向隊列裡面非同步添加10個block for (int i = 0; i<10; i++) { dispatch_async(queue, ^{ NSLog(@"\n---------->非同步指派:%@--正在執行並行隊列中的第 %d 個block",[NSThread currentThread],i); }); } // 快速向隊列裡面同步添加10個block for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->同步指派:%@--正在執行並行隊列中的第 %d 個block",[NSThread currentThread],i); }); } }/* 並行隊列:分同步指派10個,再非同步指派10個 */- (void)gcd_concurrent_sync_async{ dispatch_queue_t queue = dispatch_queue_create("並行隊列", DISPATCH_QUEUE_CONCURRENT); // 快速向隊列裡面同步添加10個block for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->同步指派:%@--正在執行並行隊列中的第 %d 個block",[NSThread currentThread],i); }); } // 快速向隊列裡面非同步添加10個block for (int i = 0; i<10; i++) { dispatch_async(queue, ^{ NSLog(@"\n---------->非同步指派:%@--正在執行並行隊列中的第 %d 個block",[NSThread currentThread],i); }); }}/* 串列隊列: 1.先sync指派10個block 2.再async指派10個block */- (void)gcd_serial_sync_async{ dispatch_queue_t queue = dispatch_queue_create("串列隊列", DISPATCH_QUEUE_SERIAL); // 快速向隊列裡面添加10個block for (int i = 0; i<10; i++) { // 同步dispatch dispatch_sync(queue, ^{ NSLog(@"---------->同步指派:%@--正在執行串列隊列中的第 %d 個block",[NSThread currentThread],i); }); } // 快速向隊列裡面添加10個block for (int i = 0; i<10; i++) { // 非同步dispatch dispatch_async(queue, ^{ NSLog(@"---------->非同步指派:%@--正在執行串列隊列中的第 %d 個block",[NSThread currentThread],i); }); } }/* 並發隊列+同步dispatch 關鍵:同步,則不會開新線程,直接使用主線程, 雖然是並發隊列,但由於 可有一個執行路線,所以會順序執行 */- (void)gcd_concurrent_sync{ // 參數1:是調試用的,是C字串, // 參數2:A dispatch queue that may invoke blocks concurrently and supports // barrier blocks submitted with the dispatch barrier API. dispatch_queue_t queue = dispatch_queue_create("並行隊列", DISPATCH_QUEUE_CONCURRENT); // 快速向隊列裡面添加10個block for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->同步指派:%@--正在執行並行隊列中的第 %d 個block",[NSThread currentThread],i); }); } }/* 並發隊列+非同步dispatch 關鍵:開多條新線程(具體開幾個無法控制),block執行沒有順序,程式員無法控制執行順序 */- (void)gcd_concurrent_async{ // 參數1:是調試用的,是C字串, // 參數2:A dispatch queue that may invoke blocks concurrently and supports // barrier blocks submitted with the dispatch barrier API. dispatch_queue_t queue = dispatch_queue_create("並行隊列", DISPATCH_QUEUE_CONCURRENT); // 快速向隊列裡面添加10個block for (int i = 0; i<10; i++) { dispatch_async(queue, ^{ NSLog(@"\n---------->非同步指派:%@--正在執行並行隊列中的第 %d 個block",[NSThread currentThread],i); }); } }/* 串列隊列 + 同步dispatch 【極少使用】 既然是 同步dispatch,就沒有必要開一條新線程,在主線程上 一個接一個block執行 */- (void)gcd_serial_sync{ // 參數1:是調試用的,是C字串, // 參數2:A dispatch queue that invokes blocks serially in FIFO order. dispatch_queue_t queue = dispatch_queue_create("串列隊列", DISPATCH_QUEUE_SERIAL); // 快速向隊列裡面添加 for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->線程:%@--正在執行串列隊列中的第 %d 個block",[NSThread currentThread],i); }); } }/* 1、串列隊列裡面的非同步任務 這個非常有用,舉例如下: 一個串列的隊列裡,先執行 下載圖片的block 然後再執行濾鏡操作(如 紅眼、高光、羽化等blcok) 最後再執行儲存block */- (void)gcd_serial_async{ // 參數1:是調試用的,是C字串, // 參數2:A dispatch queue that invokes blocks serially in FIFO order. dispatch_queue_t queue = dispatch_queue_create("串列隊列", DISPATCH_QUEUE_SERIAL); // 快速向隊列裡面添加 for (int i = 0; i<10; i++) { // Submits a block for asynchronous execution on a dispatch queue. // Calls to dispatch_async() always return immediately after the block has // been submitted, and never wait for the block to be invoked. dispatch_async(queue, ^{ NSLog(@"\n---------->線程:%@--正在執行串列隊列中的第 %d 個block",[NSThread currentThread],i); }); } }@end
串列隊列: 同步裡面嵌套了同步,結果是:【永遠也不會執行】
因為:理論上 是在主線程 執行完 第一個block,再執行 被添加到queue裡面的第2個block,但是:由於 第1個block沒執行完,是不會執行 後來添加到queue裡面的第2個block,因此阻塞住了,第2個被添加到queue裡面的block永遠不會被執行