iOS_多線程_GCD,ios多線程_gcd

來源:互聯網
上載者:User

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永遠不會被執行


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.