麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

iOS開發(fā)之GCD基礎(chǔ)

2019-11-14 20:23:06
字體:
供稿:網(wǎng)友

重新回顧、學(xué)習(xí)GCD、Block。先貼出一篇不錯(cuò)的講解GCD基礎(chǔ)使用的文章

原文地址:http://blog.csdn.net/aolan1108/article/details/17283415

 

 

做了2年的ios開發(fā),很想靜下心來想想,做一些總結(jié),但是苦于生活和工作方面的種種原因,一直沒能如愿。今天終于下定決心,把自己所學(xué)所想記錄下來,方便以后查看,同時(shí)可供大家分享。

 
就像之前說的,做了兩年的ios開發(fā),只知道不斷的copy代碼,如果你要真的問我GCD是神馬東東,我一時(shí)半會(huì)也說不清楚。這里我要為自己生存在互聯(lián)網(wǎng)時(shí)代感覺到慶幸,我在網(wǎng)上翻閱了很多資料,大都不太完整,在這些資料中,我不斷篩選,終于把GCD給整明白了。我不喜歡說官方的話,說一個(gè)東西,從他的定義開始,這個(gè)比較俗套,如果大家真的不明白GCD是啥意思,可以自己找去。
 
隊(duì)列種類:
一、主線程的Main queue,通過dispatch_get_main_queue獲取。
二、并行隊(duì)列g(shù)lobal dispatch queue,通過dispatch_get_global_queue獲取,由系統(tǒng)創(chuàng)建(不需要開發(fā)人員去創(chuàng)建)三個(gè)不同優(yōu)先級(jí)的dispatch queue。并行隊(duì)列的執(zhí)行順序與其加入隊(duì)列的順序相同。
三、串行隊(duì)列serial queues一般用于按順序同步訪問,可創(chuàng)建任意數(shù)量的串行隊(duì)列,各個(gè)串行隊(duì)列之間是并發(fā)的。一般用dispatch_queue_create來進(jìn)行創(chuàng)建,非arc的情況下需要用戶手動(dòng)來釋放隊(duì)列,可能會(huì)有人說,既然隊(duì)列也是一種對(duì)象,可以創(chuàng)建和釋放,那一定會(huì)有引用計(jì)數(shù)器了,是的,可以使用函數(shù)dispatch_retain和dispatch_release來增加或者減少引用計(jì)數(shù)器。
 
提交job:
在舉例子給大家看之前,我還想說說兩種提交job的方式:dispatch_async和dispatch_sync,分別是異步執(zhí)行和同步執(zhí)行,兩者之前的區(qū)別在于,前者在把任務(wù)提交到隊(duì)列執(zhí)行不會(huì)造成阻塞,而后者后面的代碼塊需要等到隊(duì)列中的任務(wù)執(zhí)行完成后才可以執(zhí)行。
 
下面是例子
 
例子一,我們可以看到首先執(zhí)行的是第二條打印語句,這說明這條語句沒有被阻塞。
 
[objc] view plaincopy
 
  1. //主線程異步執(zhí)行  -(void)action1{                    dispatch_async(dispatch_get_main_queue(), ^{                    for (int i = 0; i< 5; i++) NSLog(@"主線程異步執(zhí)行===========%d",i);                            });                    NSLog(@"=================主線程異步執(zhí)行");      }  

     



打印結(jié)果:
 

2013-12-09 14:36:20.863 TestGCD[872:a0b] =================主線程異步執(zhí)行

2013-12-09 14:36:20.864 TestGCD[872:a0b] 主線程異步執(zhí)行===========0

2013-12-09 14:36:20.865 TestGCD[872:a0b] 主線程異步執(zhí)行===========1

2013-12-09 14:36:20.865 TestGCD[872:a0b] 主線程異步執(zhí)行===========2

2013-12-09 14:36:20.865 TestGCD[872:a0b] 主線程異步執(zhí)行===========3

2013-12-09 14:36:20.866 TestGCD[872:a0b] 主線程異步執(zhí)行===========4

 
 
 
 
 
例子二,會(huì)有人問,既然主線程可以異步執(zhí)行,那么主線程也可以同步執(zhí)行嘍。的確是可以的,但是不能直接在action1里面將dispatch_async改為dispatch_sync,這樣修改是沒有意義的,大家可以試試,里面的任務(wù)根本不會(huì)執(zhí)行。
 
[objc] view plaincopy
 
  1. //主線程同步執(zhí)行  -(void)action2{            dispatch_async(dispatch_get_global_queue(0, 0), ^{                    for (int i = 0; i< 3; i++) NSLog(@"并發(fā)線程異步執(zhí)行===========%d",i);                    dispatch_sync(dispatch_get_main_queue(), ^{                            for (int i = 0; i< 3; i++) NSLog(@"主線程同步執(zhí)行===========%d",i);                        });                     NSLog(@"===========主線程執(zhí)行完畢");      });             NSLog(@"===========并發(fā)線程可能正在執(zhí)行");  }  

     

打印結(jié)果:

 

2013-12-09 15:22:22.352 TestGCD[1269:a0b] ===========并發(fā)線程可能正在執(zhí)行

2013-12-09 15:22:22.352 TestGCD[1269:1403] 并發(fā)線程異步執(zhí)行===========0

2013-12-09 15:22:22.355 TestGCD[1269:1403] 并發(fā)線程異步執(zhí)行===========1

2013-12-09 15:22:22.356 TestGCD[1269:1403] 并發(fā)線程異步執(zhí)行===========2

2013-12-09 15:22:22.357 TestGCD[1269:a0b] 主線程同步執(zhí)行===========0

2013-12-09 15:22:22.358 TestGCD[1269:a0b] 主線程同步執(zhí)行===========1

2013-12-09 15:22:22.358 TestGCD[1269:a0b] 主線程同步執(zhí)行===========2

2013-12-09 15:22:22.359 TestGCD[1269:1403] ===========主線程執(zhí)行完畢

 

從結(jié)果中我們仔細(xì)理解,就會(huì)比較深刻,首先我們看到打印語句4最先執(zhí)行(有可能不是最先執(zhí)行,這個(gè)是由系統(tǒng)決定的),說明我們提交到并發(fā)隊(duì)列dispatch_get_global_queue的執(zhí)行方式是異步的;其次打印語句2是在打印語句1執(zhí)行完才開始執(zhí)行,這說明dispatch_get_global_queue雖然是并發(fā)隊(duì)列,但是其內(nèi)部的任務(wù)執(zhí)行順序是串行的;最后,我們看到打印語句3是在打印語句2執(zhí)行完成后再執(zhí)行,說明主線程同步執(zhí)行是阻塞的,我們通常會(huì)將UI的刷新用同步方式放到主線程中去操作,當(dāng)然這種操作的時(shí)間一般都比較短,以至于用戶幾乎無法察覺。

 

例子三,其實(shí)GCD的操作真正的意義當(dāng)然不在于在主線程中做一些操作,在很多時(shí)候,我們都會(huì)用到后臺(tái)線程,如果你的iphone是多核的cpu,那么恭喜你,你可以有流暢的操作體驗(yàn),即使不是多核,你的操作體驗(yàn)也相對(duì)流暢,因?yàn)槟憧梢詫⑿枰罅繒r(shí)間才能執(zhí)行完成的任務(wù)放到后臺(tái)線程中去執(zhí)行,用戶就不會(huì)有死機(jī)感,譬如說圖片加載、網(wǎng)絡(luò)請(qǐng)求、復(fù)雜邏輯的數(shù)據(jù)解析等等。

 

//后臺(tái)異步執(zhí)行  
-(void)action3{            dispatch_async(dispatch_get_global_queue(0, 0), ^{                    for (int i = 0; i< 10000; i++) NSLog(@"=================%d",i);                });            NSLog(@"=================后臺(tái)異步執(zhí)行");  } 

 

 

你可以迅速點(diǎn)擊兩次按鈕,即連續(xù)執(zhí)行兩次action3方法,在這里,我們截取部分打印結(jié)果:

 

 

2013-12-09 15:51:30.864 TestGCD[1350:3007] =================0

2013-12-09 15:51:30.864 TestGCD[1350:a0b] =================后臺(tái)異步執(zhí)行

2013-12-09 15:51:30.864 TestGCD[1350:3007] =================1

2013-12-09 15:51:30.865 TestGCD[1350:3007] =================2

2013-12-09 15:51:30.865 TestGCD[1350:3007] =================3

......

 

2013-12-09 15:51:31.007 TestGCD[1350:3007] =================600

2013-12-09 15:51:31.007 TestGCD[1350:3007] =================601

2013-12-09 15:51:31.007 TestGCD[1350:a0b] =================后臺(tái)異步執(zhí)行

2013-12-09 15:51:31.007 TestGCD[1350:3007] =================602

2013-12-09 15:51:31.008 TestGCD[1350:3007] =================603

2013-12-09 15:51:31.007 TestGCD[1350:473] =================0

2013-12-09 15:51:31.008 TestGCD[1350:473] =================1

2013-12-09 15:51:31.008 TestGCD[1350:473] =================2

2013-12-09 15:51:31.008 TestGCD[1350:3007] =================604

2013-12-09 15:51:31.008 TestGCD[1350:473] =================3

2013-12-09 15:51:31.008 TestGCD[1350:3007] =================605

......

 

我們看到由于action3被執(zhí)行了兩次,在點(diǎn)擊第一次后,屏幕仍然接受點(diǎn)擊時(shí)間,說明主線程沒有被阻塞,用戶體驗(yàn)仍然很流暢。兩次點(diǎn)擊實(shí)際上是提交了兩個(gè)任務(wù)到dispatch_get_global_queue隊(duì)列上,第一次任務(wù)并沒有執(zhí)行完成,第二次任務(wù)就開始執(zhí)行,說明dispatch_get_global_queue是并行隊(duì)列,即任務(wù)塊與任務(wù)塊之間是并發(fā)執(zhí)行的。

 

 

 

例子四,肯定會(huì)有小伙伴們說后臺(tái)既然可以異步執(zhí)行,那么應(yīng)該也可以同步執(zhí)行嘍,是的,你是對(duì)的,但是在實(shí)際的開發(fā)過程中沒有什么意義,我們會(huì)發(fā)現(xiàn)改方法會(huì)產(chǎn)生阻塞,但是卻不能用來刷新UI,也沒有體現(xiàn)多核處理器的優(yōu)勢(shì)。

 

  1. //后臺(tái)同步執(zhí)行  -(void)action4{            dispatch_sync(dispatch_get_global_queue(0, 0), ^{                    for (int i = 0; i< 10000; i++) NSLog(@"=================%d",i);                });            NSLog(@"=================后臺(tái)同步執(zhí)行");  }  

     

我們也是連續(xù)點(diǎn)擊兩次按鈕,執(zhí)行兩次action4方法,我們看到的打印結(jié)果讓我們很驚訝,可能會(huì)有人說,dispatch_get_global_queue隊(duì)列不是并發(fā)隊(duì)列嗎,怎么執(zhí)行的結(jié)果是這樣的。在這里我需要解釋下,由于提交給全局隊(duì)列的執(zhí)行方式是同步的,這里實(shí)際上是產(chǎn)生了阻塞,即必須是該任務(wù)完成后才能執(zhí)行下面的任務(wù),我們看到打印語句2執(zhí)行的位置就知道了。所以同步一般在刷新UI界面或者處理共享數(shù)據(jù)的時(shí)候使用,而且任務(wù)的處理時(shí)間不能太長(zhǎng),會(huì)影響用戶體驗(yàn)。

 

 

2013-12-09 16:04:35.967 TestGCD[1385:a0b] =================0

2013-12-09 16:04:35.969 TestGCD[1385:a0b] =================1

2013-12-09 16:04:35.969 TestGCD[1385:a0b] =================2

......

2013-12-09 16:04:40.645 TestGCD[1385:a0b] =================9997

2013-12-09 16:04:40.645 TestGCD[1385:a0b] =================9998

2013-12-09 16:04:40.646 TestGCD[1385:a0b] =================9999

2013-12-09 16:04:40.646 TestGCD[1385:a0b] =================后臺(tái)同步執(zhí)行

2013-12-09 16:04:40.647 TestGCD[1385:a0b] =================0

2013-12-09 16:04:40.647 TestGCD[1385:a0b] =================1

2013-12-09 16:04:40.648 TestGCD[1385:a0b] =================2

2013-12-09 16:04:40.648 TestGCD[1385:a0b] =================3

......

 

2013-12-09 16:04:45.218 TestGCD[1385:a0b] =================9998

2013-12-09 16:04:45.218 TestGCD[1385:a0b] =================9999

2013-12-09 16:04:45.218 TestGCD[1385:a0b] =================后臺(tái)同步執(zhí)行

 

 

 

例子五,開發(fā)人員可以自己定義一個(gè)隊(duì)列用于執(zhí)行后臺(tái)線程,同全局隊(duì)列使用方法基本類似,在非arc的情況下,需要開發(fā)人員手動(dòng)釋放。

 

 
  1. //自定義dispatch_queue_t  -(void)action5{            dispatch_queue_t urls_queue = dispatch_queue_create("myQueue", NULL);            dispatch_async(urls_queue, ^{                    for (int i = 0; i< 5; i++) NSLog(@"自定義dispatch_queue_t===========%d",i);                    dispatch_sync(dispatch_get_main_queue(), ^{                           NSLog(@"同主線程交互===========");          });        });            dispatch_release(urls_queue);   //arc不要  }  

     

打印結(jié)果:

 

 

2013-12-09 16:43:52.416 TestGCD[1464:1417] 自定義dispatch_queue_t===========0

2013-12-09 16:43:52.417 TestGCD[1464:1417] 自定義dispatch_queue_t===========1

2013-12-09 16:43:52.418 TestGCD[1464:1417] 自定義dispatch_queue_t===========2

2013-12-09 16:43:52.419 TestGCD[1464:1417] 自定義dispatch_queue_t===========3

2013-12-09 16:43:52.420 TestGCD[1464:1417] 自定義dispatch_queue_t===========4

2013-12-09 16:43:52.420 TestGCD[1464:a0b] 同主線程交互===========

 

 

例子六,除此之外,調(diào)度方式還有延遲執(zhí)行。

 

 

  1. //延遲3秒執(zhí)行  -(void)action6{            double delayInSeconds = 3.0;      dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));      dispatch_after(popTime, dispatch_get_main_queue(), ^(void){                    NSLog(@"延遲3秒執(zhí)行===========");        });  }  

     

打印結(jié)果:

 

 

2013-12-09 16:48:58.473 TestGCD[1484:a0b] 延遲3秒執(zhí)行===========

 
 

例子七,一次性執(zhí)行,主要用于創(chuàng)建單例對(duì)象。在ios4.0以前,我們創(chuàng)建單例會(huì)用到互斥鎖@synchronized來確保其他線程沒有對(duì)self對(duì)象進(jìn)行修改,一般在共用變量的時(shí)候使用。

 
  1. + (NetworkManager *)getNetworkInstance{         @synchronized(self){                    if (nil == network) network = [[NetworkManager alloc] init];      }          return network;  }  

     

ios4.0之后,我們可以用GCD創(chuàng)建單例,下面的GCD語法只會(huì)執(zhí)行一次,代碼如下:

 

 
  1. +(UserManager *)sharedManager{            static UserManager *_manager = nil;            static dispatch_once_t onceToken;            dispatch_once(&onceToken, ^{                    _manager = [[UserManager alloc]init];        });            return _manager;  }  

     

該方法的好處有:一、線程安全;二、很好滿足靜態(tài)分析器的要求;三、兼容ARC;四、僅需要少量代碼。

 

 

 

例子八,合并匯總結(jié)果,dispatch_group_t隊(duì)列非常好用,當(dāng)我們有多個(gè)異步執(zhí)行的隊(duì)列在執(zhí)行,我們還有一個(gè)任務(wù)需要用到這多個(gè)異步執(zhí)行隊(duì)列執(zhí)行的結(jié)果時(shí),我們就會(huì)用到dispatch_group_t,廢話不多說,直接上代碼:

 

 

 
  1. //合并匯總結(jié)果  -(void)action8{         dispatch_group_t group = dispatch_group_create();            dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{                    for (int i = 0; i < 5; i++) NSLog(@"并行執(zhí)行的線程一=============%d",i);      });            dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{                    for (int i = 0; i < 5; i++) NSLog(@"并行執(zhí)行的線程二=============%d",i);        });            dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{                   NSLog(@"匯總結(jié)果===========");        });            dispatch_release(group);  }  

     

 

打印結(jié)果:
 

2013-12-10 11:48:39.139 TestGCD[699:1403] 并行執(zhí)行的線程一=============0

2013-12-10 11:48:39.139 TestGCD[699:3807] 并行執(zhí)行的線程二=============0

2013-12-10 11:48:39.143 TestGCD[699:1403] 并行執(zhí)行的線程一=============1

2013-12-10 11:48:39.143 TestGCD[699:3807] 并行執(zhí)行的線程二=============1

2013-12-10 11:48:39.144 TestGCD[699:1403] 并行執(zhí)行的線程一=============2

2013-12-10 11:48:39.144 TestGCD[699:3807] 并行執(zhí)行的線程二=============2

2013-12-10 11:48:39.145 TestGCD[699:1403] 并行執(zhí)行的線程一=============3

2013-12-10 11:48:39.145 TestGCD[699:3807] 并行執(zhí)行的線程二=============3

2013-12-10 11:48:39.146 TestGCD[699:3807] 并行執(zhí)行的線程二=============4

2013-12-10 11:48:39.146 TestGCD[699:1403] 并行執(zhí)行的線程一=============4

2013-12-10 11:48:39.147 TestGCD[699:3807] 匯總結(jié)果===========

 

我們看到第三條打印語句是在前兩條打印語句執(zhí)行之后才執(zhí)行。

 

這也是我綜合了官方文檔和網(wǎng)上的很多資料總結(jié)出來的,并且用實(shí)際的代碼調(diào)試出來的結(jié)果,希望能給大家一些幫助,對(duì)于其中的不足,歡迎大家給出不同意見。

 

 

參考:http://www.companysz.com/pure/archive/2013/03/31/2977420.html

 

 

 

 

2014_07_16今天再次翻看GCD。再瀏覽過程中,發(fā)現(xiàn)了另外一篇不錯(cuò)的講解隊(duì)列的帖子,現(xiàn)轉(zhuǎn)發(fā)之,希望能對(duì)你有所幫助和啟發(fā),里面提到死鎖的問題,可以思考和交流。

原文地址:http://www.companysz.com/sunfrog/p/3305614.html

GCD編程的核心就是dispatch隊(duì)列,dispatch block的執(zhí)行最終都會(huì)放進(jìn)某個(gè)隊(duì)列中去進(jìn)行,它類似NSOperationQueue但更復(fù)雜也更強(qiáng)大,并且可以嵌套使用。所以說,結(jié)合block實(shí)現(xiàn)的GCD,把函數(shù)閉包(Closure)的特性發(fā)揮得淋漓盡致。

 

dispatch隊(duì)列的生成可以有這幾種方式:

1. dispatch_queue_t queue = dispatch_queue_create("com.dispatch.serial"DISPATCH_QUEUE_SERIAL); //生成一個(gè)串行隊(duì)列,隊(duì)列中的block按照先進(jìn)先出(FIFO)的順序去執(zhí)行,實(shí)際上為單線程執(zhí)行。第一個(gè)參數(shù)是隊(duì)列的名稱,在調(diào)試程序時(shí)會(huì)非常有用,所有盡量不要重名了。

2. dispatch_queue_t queue = dispatch_queue_create("com.dispatch.concurrent"DISPATCH_QUEUE_CONCURRENT); //生成一個(gè)并發(fā)執(zhí)行隊(duì)列,block被分發(fā)到多個(gè)線程去執(zhí)行

3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //獲得程序進(jìn)程缺省產(chǎn)生的并發(fā)隊(duì)列,可設(shè)定優(yōu)先級(jí)來選擇高、中、低三個(gè)優(yōu)先級(jí)隊(duì)列。由于是系統(tǒng)默認(rèn)生成的,所以無法調(diào)用dispatch_resume()和dispatch_suspend()來控制執(zhí)行繼續(xù)或中斷。需要注意的是,三個(gè)隊(duì)列不代表三個(gè)線程,可能會(huì)有更多的線程。并發(fā)隊(duì)列可以根據(jù)實(shí)際情況來自動(dòng)產(chǎn)生合理的線程數(shù),也可理解為dispatch隊(duì)列實(shí)現(xiàn)了一個(gè)線程池的管理,對(duì)于程序邏輯是透明的。

官網(wǎng)文檔解釋說共有三個(gè)并發(fā)隊(duì)列,但實(shí)際還有一個(gè)更低優(yōu)先級(jí)的隊(duì)列,設(shè)置優(yōu)先級(jí)為DISPATCH_QUEUE_PRIORITY_BACKGROUND。Xcode調(diào)試時(shí)可以觀察到正在使用的各個(gè)dispatch隊(duì)列。

4. dispatch_queue_t queue = dispatch_get_main_queue(); //獲得主線程的dispatch隊(duì)列,實(shí)際是一個(gè)串行隊(duì)列。同樣無法控制主線程dispatch隊(duì)列的執(zhí)行繼續(xù)或中斷。

接下來我們可以使用dispatch_async或dispatch_sync函數(shù)來加載需要運(yùn)行的block。

dispatch_async(queue, ^{

  //block具體代碼

}); //異步執(zhí)行block,函數(shù)立即返回

dispatch_sync(queue, ^{

  //block具體代碼

}); //同步執(zhí)行block,函數(shù)不返回,一直等到block執(zhí)行完畢。編譯器會(huì)根據(jù)實(shí)際情況優(yōu)化代碼,所以有時(shí)候你會(huì)發(fā)現(xiàn)block其實(shí)還在當(dāng)前線程上執(zhí)行,并沒用產(chǎn)生新線程。

實(shí)際編程經(jīng)驗(yàn)告訴我們,盡可能避免使用dispatch_sync,嵌套使用時(shí)還容易引起程序死鎖。

如果queue1是一個(gè)串行隊(duì)列的話,這段代碼立即產(chǎn)生死鎖:

   dispatch_sync(queue1, ^{

      dispatch_sync(queue1, ^{

    ......

  });

  ......

 });

不妨思考下,為什么下面代碼在主線程中執(zhí)行會(huì)死鎖:

dispatch_sync(dispatch_get_main_queue(), ^{

  ......

}); 

 

那實(shí)際運(yùn)用中,一般可以用dispatch這樣來寫,常見的網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)多線程執(zhí)行模型:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  //子線程中開始網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)

  //更新數(shù)據(jù)模型

  dispatch_sync(dispatch_get_main_queue(), ^{

    //在主線程中更新UI代碼

  });

});

程序的后臺(tái)運(yùn)行和UI更新代碼緊湊,代碼邏輯一目了然。

 

dispatch隊(duì)列是線程安全的,可以利用串行隊(duì)列實(shí)現(xiàn)鎖的功能。比如多線程寫同一數(shù)據(jù)庫,需要保持寫入的順序和每次寫入的完整性,簡(jiǎn)單地利用串行隊(duì)列即可實(shí)現(xiàn):

dispatch_queue_t queue1 = dispatch_queue_create("com.dispatch.writedb"DISPATCH_QUEUE_SERIAL);

- (void)writeDB:(NSData *)data

{

  dispatch_async(queue1, ^{

    //write database

  });

} 

下一次調(diào)用writeDB:必須等到上次調(diào)用完成后才能進(jìn)行,保證writeDB:方法是線程安全的。 

 

dispatch隊(duì)列還實(shí)現(xiàn)其它一些常用函數(shù),包括:

void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t)); //重復(fù)執(zhí)行block,需要注意的是這個(gè)方法是同步返回,也就是說等到所有block執(zhí)行完畢才返回,如需異步返回則嵌套在dispatch_async中來使用。多個(gè)block的運(yùn)行是否并發(fā)或串行執(zhí)行也依賴queue的是否并發(fā)或串行。

void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block); //這個(gè)函數(shù)可以設(shè)置同步執(zhí)行的block,它會(huì)等到在它加入隊(duì)列之前的block執(zhí)行完畢后,才開始執(zhí)行。在它之后加入隊(duì)列的block,則等到這個(gè)block執(zhí)行完畢后才開始執(zhí)行。

void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block); //同上,除了它是同步返回函數(shù)

void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block); //延遲執(zhí)行block

最后再來看看dispatch隊(duì)列的一個(gè)很有特色的函數(shù):

void dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue);

它會(huì)把需要執(zhí)行的任務(wù)對(duì)象指定到不同的隊(duì)列中去處理,這個(gè)任務(wù)對(duì)象可以是dispatch隊(duì)列,也可以是dispatch源(以后博文會(huì)介紹)。而且這個(gè)過程可以是動(dòng)態(tài)的,可以實(shí)現(xiàn)隊(duì)列的動(dòng)態(tài)調(diào)度管理等等。比如說有兩個(gè)隊(duì)列dispatchA和dispatchB,這時(shí)把dispatchA指派到dispatchB:

dispatch_set_target_queue(dispatchA, dispatchB);

那么dispatchA上還未運(yùn)行的block會(huì)在dispatchB上運(yùn)行。這時(shí)如果暫停dispatchA運(yùn)行:

dispatch_suspend(dispatchA);

則只會(huì)暫停dispatchA上原來的block的執(zhí)行,dispatchB的block則不受影響。而如果暫停dispatchB的運(yùn)行,則會(huì)暫停dispatchA的運(yùn)行。

這里只簡(jiǎn)單舉個(gè)例子,說明dispatch隊(duì)列運(yùn)行的靈活性,在實(shí)際應(yīng)用中你會(huì)逐步發(fā)掘出它的潛力。

dispatch隊(duì)列不支持cancel(取消),沒有實(shí)現(xiàn)dispatch_cancel()函數(shù),不像NSOperationQueue,不得不說這是個(gè)小小的缺憾。 


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 成人在线视频免费观看 | 一级成人毛片 | 欧美一级黄 | sese在线视频| 最新av在线播放 | 高清在线观看av | qyl在线视频精品免费观看 | 欧美性猛交一区二区三区精品 | 久久久久久久久久久久久久久久久久 | 国内精品久久久久久久久久久久 | 欧美视频99| 成年性羞羞视频免费观看无限 | xxxxhd18hd日本hd | 国产精品久久久久久影院8一贰佰 | 亚洲最大的成人网 | 久久蜜桃精品一区二区三区综合网 | 国产精品99久久久久久宅女 | 国产精品午夜一区 | 性生活视频软件 | 亚洲午夜久久久精品一区二区三区 | 色婷婷a v| 日本残忍极度灌浣肠视频 | 一区二区三区精品国产 | 一级美女大片 | 免费看成年人视频在线 | 一区在线不卡 | 欧美成人一区二区三区 | 精品国产一区二区三 | 久久亚洲成人网 | 露脸各种姿势啪啪的清纯美女 | 免费a级毛片永久免费 | 国产九九九九 | 女人一级一级毛片 | 色淫视频 | 精品国产一区二区三区四区阿崩 | 欧美一级特黄aaaaaa在线看首页 | 黄色的视频免费看 | 717影院理论午夜伦八戒秦先生 | 国产精品久久久久久久久久东京 | 深夜小视频在线观看 | 成年免费在线视频 |