偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

詳解IOS開發(fā)應(yīng)用之并發(fā)Dispatch Queues

移動(dòng)開發(fā) iOS
詳解IOS開發(fā)應(yīng)用之并發(fā)Dispatch Queues是本文喲啊介紹的內(nèi)容,我們幾乎可以調(diào)度隊(duì)列去完成所有用線程來完成的任務(wù)。

詳解IOS開發(fā)應(yīng)用之并發(fā)Dispatch Queues是本文喲啊介紹的內(nèi)容,我們幾乎可以調(diào)度隊(duì)列去完成所有用線程來完成的任務(wù)。調(diào)度隊(duì)列相對(duì)于線程代碼更簡(jiǎn)單,易于使用,更高效。下面講主要簡(jiǎn)述調(diào)度隊(duì)列,在應(yīng)用中如何使用調(diào)度隊(duì)列去執(zhí)行任務(wù)。

1、關(guān)于調(diào)度隊(duì)列

所有的調(diào)度隊(duì)列都是先進(jìn)先出隊(duì)列,因此,隊(duì)列中的任務(wù)的開始的順序和添加到隊(duì)列中的順序相同。GCD自動(dòng)的為我們提供了一些調(diào)度隊(duì)列,我們也可以創(chuàng)建新的用于具體的目的。

下面列出幾種可用的調(diào)度隊(duì)列類型以及如何使用。

(1)serial queues(串行隊(duì)列)又稱私有調(diào)度隊(duì)列(private),一般用再對(duì)特定資源的同步訪問上。我們可以根據(jù)需要?jiǎng)?chuàng)建任意數(shù)量的串行隊(duì)列,每一個(gè)串行隊(duì)列之間是并發(fā)的。

(2)并行隊(duì)列,又稱global dispatch queue。并行隊(duì)列雖然可以并發(fā)的執(zhí)行多個(gè)任務(wù),但是任務(wù)開始執(zhí)行的順序和其加入隊(duì)列的順序相同。我們自己不能去創(chuàng)建并行調(diào)度隊(duì)列。只有三個(gè)可用的global concurrent queues。

(3)main dispatch queue 是一個(gè)全局可用的串行隊(duì)列,其在行用程序的主線程上執(zhí)行任務(wù)。此隊(duì)列的任務(wù)和應(yīng)用程序的主循環(huán)(run loop)要執(zhí)行的事件源交替執(zhí)行。因?yàn)槠溥\(yùn)行在應(yīng)用程序的主線程,main queue經(jīng)常用來作為應(yīng)用程序的一個(gè)同步點(diǎn)。

2、關(guān)于隊(duì)列的一些技術(shù)

除了調(diào)度隊(duì)列,GCD還提供了一些有用的技術(shù)來幫助我們管理代碼。

  1. dispath group ,dispatch semaphore, dispath sources 

3、使用blocks去實(shí)現(xiàn)tasks

block objects是基于C語(yǔ)言的特征,可以用在C,C++ Objective-c中。一個(gè)block雖然和函數(shù)指針有些相似,但是實(shí)際上代表一個(gè)底層數(shù)據(jù)結(jié)構(gòu),類似與對(duì)象,有編譯器去創(chuàng)建和管理。

block的一個(gè)優(yōu)勢(shì)是可以使用其自己作用域外的變量,例如,一個(gè)block可以讀取其父作用域的變量值,此值是copy到了block heap的數(shù)據(jù)結(jié)構(gòu)中。當(dāng)block被加入到dispatch queue中,這些值通常為只讀形式。

block的聲明和函數(shù)指針類似,只是把*改為了^,我們可以傳遞參數(shù)給block,也可以接收其返回的值。

4、創(chuàng)建和管理調(diào)度隊(duì)列

(1)獲得全局并發(fā)調(diào)度隊(duì)列(global concurrent dispath queues)

系統(tǒng)給每一個(gè)應(yīng)用程序提供了三個(gè)concurrent dispatch queues。這三個(gè)并發(fā)調(diào)度隊(duì)列是全局的,它們只有優(yōu)先級(jí)的不同。因?yàn)槭侨值?,我們不需要去?chuàng)建。我們只需要通過使用函數(shù)dispath_get_global_queue去得到隊(duì)列,如下:

  1. dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  

除了得到default的并發(fā)隊(duì)列,還可以通過傳遞參數(shù)DISPATCH_QUEUE_PRIOPITY_HIGH和DISPATCH_QUEUE_PRIOPITY_LOW去得到高優(yōu)先級(jí)或者低優(yōu)先級(jí)的。(第二個(gè)參數(shù)是為以后擴(kuò)展保留的)

雖然dispatch queue是引用計(jì)數(shù)對(duì)象,但是在此因?yàn)殛?duì)列是全局的,不需要我們?nèi)etain或者release,我們需要使用的時(shí)候直接調(diào)用函數(shù)dispath_get_global_queue就可以。

(2)創(chuàng)建串行調(diào)度隊(duì)列

當(dāng)想要任務(wù)按照某一個(gè)特定的順序執(zhí)行時(shí),串行隊(duì)列是很有用的。串行隊(duì)列在同一個(gè)時(shí)間只執(zhí)行一個(gè)任務(wù)。我們可以使用串行隊(duì)列代替鎖去保護(hù)共享的數(shù)據(jù)。和鎖不同,一個(gè)串行隊(duì)列可以保證任務(wù)在一個(gè)可預(yù)知的順序下執(zhí)行。

和并發(fā)隊(duì)列不同,我們要自己去創(chuàng)建和管理串行隊(duì)列,可以創(chuàng)建任意數(shù)量的串行隊(duì)列。當(dāng)我們創(chuàng)建串行隊(duì)列時(shí),應(yīng)出于某種目的,如保護(hù)資源,或者同步應(yīng)用程序的某些關(guān)鍵行為。

下面的代碼表述了怎么創(chuàng)建一個(gè)自定義的串行隊(duì)列,函數(shù)dispath_queue_create需要兩個(gè)參數(shù),隊(duì)列的名字,隊(duì)列的屬性。調(diào)試器和性能工具顯示隊(duì)列的名字幫助我們?nèi)ジ櫲蝿?wù)是如何執(zhí)行,隊(duì)列的屬性被保留供將來使用,應(yīng)該為NULL

  1. dispatch_queue_t queue;  
  2. queue = dispatch_queue_create("com.example.MyQueue", NULL); 

除了自己創(chuàng)建的自定義隊(duì)列,系統(tǒng)會(huì)自動(dòng)的給我創(chuàng)建一個(gè)串行隊(duì)列并和應(yīng)用程序的主線程綁定到一起。下面講述如何獲得它。

(3)運(yùn)行時(shí)獲得常見的隊(duì)列

GCD提供了一些函數(shù)讓我們能夠方便的訪問到common dispatch queues

使用dispatch_get_current_queue函數(shù)用來調(diào)試或者測(cè)試獲得當(dāng)前隊(duì)列的標(biāo)識(shí)。
  
使用函數(shù)dispatch_get_main_queue可以得到與應(yīng)用程序主線程相連的串行調(diào)度隊(duì)列。

(4)調(diào)度隊(duì)列的內(nèi)存管理

調(diào)度隊(duì)列是引用計(jì)數(shù)類型,當(dāng)我們創(chuàng)建串行調(diào)度隊(duì)列時(shí),我們要release它。可以使用函數(shù)dispatch_retain和dispatch_release去增加或者減少引用計(jì)數(shù)。

(5)在一個(gè)隊(duì)列中存儲(chǔ)自定義context information

所有的調(diào)度對(duì)象允許我們讓其與一個(gè)自定義上下文數(shù)據(jù)關(guān)聯(lián),通過函數(shù)dispatch_set_context和dispatch_get_context來使用,系統(tǒng)不會(huì)去使用我們的自定義數(shù)據(jù),我們自己在恰當(dāng)?shù)臅r(shí)間去分配和釋放。

對(duì)于隊(duì)列,上下文數(shù)據(jù)通常用來存儲(chǔ)一個(gè)指向?qū)ο蟮闹羔槪蛘咂渌臄?shù)據(jù)結(jié)構(gòu),我們可以在隊(duì)列的finalizer函數(shù)中去釋放context data。下面將給一個(gè)例子。

(6)為隊(duì)列提供一個(gè)clean up 函數(shù)。

當(dāng)我們創(chuàng)建串行調(diào)度隊(duì)列之后,我們可以讓其和一個(gè)finalizer函數(shù)相連用來清理隊(duì)列中需要清理的數(shù)據(jù)。我們可以使用dispatch_set_finalizer_f函數(shù)去設(shè)置一個(gè)函數(shù),當(dāng)隊(duì)列的引用計(jì)數(shù)為0時(shí)會(huì)去自動(dòng)的調(diào)用。使用此函數(shù)去清理和隊(duì)列相關(guān)聯(lián)的context data,當(dāng)context 指針不會(huì)NULL時(shí),此函數(shù)就會(huì)調(diào)用。

 

  1. shows a custom finalizer function and a function that creates a queue and installs that finalizer.   
  2. The queue uses the finalizer function to release the data stored in the queue’s context pointer.   
  3. (The myInitializeDataContextFunction and myCleanUpDataContextFunction functions referenced from the code are custom functions that   
  4. you would provide to initialize and clean up the contents of the data structure itself.)   
  5. The context pointer passed to the finalizer function contains the data object associated with the queue. 
  1. void myFinalizerFunction(void *context)  
  2. {  
  3. MyDataContext* theData = (MyDataContext*)context;  
  4. // Clean up the contents of the structure  
  5. myCleanUpDataContextFunction(theData);  
  6. // Now release the structure itself.  
  7. free(theData);  
  8. }  
  9. dispatch_queue_t createMyQueue()  
  10. {  
  11. MyDataContext* data = (MyDataContext*) malloc(sizeof(MyDataContext));  
  12. myInitializeDataContextFunction(data);  
  13. // Create the queue and set the context data.  
  14. dispatch_queue_t serialQueue = dispatch_queue_create("com.example.CriticalTaskQueue", NULL);  
  15. if (serialQueue)  
  16. {  
  17. dispatch_set_context(serialQueue, data);  
  18. dispatch_set_finalizer_f(serialQueue, &myFinalizerFunction);  
  19. }  
  20. return serialQueue;  

5、在隊(duì)列中添加一個(gè)任務(wù)

(1)有兩種方式在隊(duì)列中添加一個(gè)任務(wù),同步或者異步。盡可能使用dispatch_async和dispatch_async_f 函數(shù)去執(zhí)行,比同步的要***。當(dāng)我們向隊(duì)列中添加一個(gè)塊對(duì)象或者函數(shù)時(shí),我們沒有方法去知道此代碼什么時(shí)間執(zhí)行。

使用此異步不會(huì)去阻塞主線程。

雖然盡可能異步添加任務(wù),在有些時(shí)候同步的方式去添加一個(gè)任務(wù)會(huì)防止一些同步錯(cuò)誤。同步的方式調(diào)用函數(shù)dispatch_sync和dispatch_sync_f。此函數(shù)阻塞主線程的執(zhí)行,直到指定的任務(wù)完成。

下面是代碼例子:

 (2)在任務(wù)完成的時(shí)候執(zhí)行completion block

當(dāng)任務(wù)完成時(shí),我們應(yīng)用程序需要得到通知,一遍去合并結(jié)果,在傳統(tǒng)的異步編程中,我們可能會(huì)使用回調(diào)函數(shù),但是在調(diào)度隊(duì)列中,我們使用completion block。

  1. void average_async(int *data, size_t len,  
  2.  
  3. dispatch_queue_t queue, void (^block)(int))  
  4. {  
  5. // Retain the queue provided by the user to make  
  6. // sure it does not disappear before the completion  
  7. // block can be called.  
  8. dispatch_retain(queue);  
  9. // Do the work on the default concurrent queue and then  
  10. // call the user-provided block with the results.  
  11. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  12. int avg = average(data, len);  
  13. dispatch_async(queue, ^{ block(avg);});  
  14. // Release the user-provided queue when done  
  15. dispatch_release(queue);  
  16. });  

(3)并發(fā)的執(zhí)行循環(huán)迭代(loop iterations)

對(duì)于for循環(huán),如果每一次的迭代相互都沒有影響,可以并發(fā)的去執(zhí)行迭代,使用函數(shù)dispatch_apply或者dispatch_apply_f 函數(shù).

和正常的循環(huán)一樣,函數(shù)dispatch_apply或者dispatch_apply_f直到所有的循環(huán)迭代完成時(shí)才返回。

如下代碼:

  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  2. dispatch_apply(count, queue, ^(size_t i) {  
  3. printf("%un",i);  
  4. }); 

(4)在主線程上執(zhí)行任務(wù)

我們可以通過調(diào)用函數(shù)dispatch_get_main_queue 去去得到主線程的調(diào)度隊(duì)列。

小結(jié):詳解IOS開發(fā)應(yīng)用之并發(fā)Dispatch Queues的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對(duì)你有所幫助!

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-08-17 14:20:21

IOS開發(fā)GraphicsCon

2011-08-17 14:30:34

iOS開發(fā)窗口

2011-08-11 17:32:51

iPhone視圖

2011-08-17 14:07:43

IOS開發(fā)Quartz 2D

2011-08-11 10:16:23

iPhoneUIView視圖

2011-08-11 10:27:37

iPhoneUIView視圖

2011-08-16 19:02:23

iPhone開發(fā)繪圖

2011-08-10 10:23:20

iPhoneArchivingNSCoder

2011-08-22 16:26:25

IOS開發(fā)Sqlite數(shù)據(jù)庫(kù)

2011-08-15 18:02:32

iPhone開發(fā)表視圖

2017-02-14 10:00:19

Java開發(fā)Lock

2011-08-12 11:31:46

iPhoneUIView動(dòng)畫

2011-08-15 10:15:00

iPhone開發(fā)警告框

2011-08-11 11:51:07

iPhone鍵盤

2018-08-15 12:43:52

iOSAndroid設(shè)計(jì)差異

2011-08-02 11:07:42

iOS開發(fā) UIWebView

2011-08-19 14:27:29

iPhone開發(fā)

2011-05-11 10:02:37

iOS

2009-07-15 09:59:36

MyEclipse使用

2009-07-15 09:59:36

MyEclipse使用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)