iOS并發(fā)編程

iOS編程中,有多種并發(fā)編程的方式,比較常見的就是基于Operation Queue和GCD,還有底層一點的NSTheard,本文主要討論Operation Queue和GCD


異步調(diào)用和并發(fā)

在談并發(fā)之前,談一談異步調(diào)用和并發(fā),異步調(diào)用是指調(diào)用時無需等待結(jié)果返回的調(diào)用。并發(fā)是指多個任務(wù)(線程)同時執(zhí)行,在異步調(diào)用的實現(xiàn)中往往用的都是并發(fā)機制,但也有可能是其他機制,比如一些依靠中斷進行的操作。(中斷:(Interrupt)是指處理器接收到來自硬件或軟件的信號,提示發(fā)生了某個事件,應(yīng)該被注意,這種情況就稱為中斷。)

Operation Queue

operation queue提供了一個面向?qū)ο蟮牟l(fā)編程接口,并支持并發(fā)數(shù)(僅operation queue支持),線程優(yōu)先級,任務(wù)優(yōu)先級,任務(wù)依賴關(guān)系等多種配置

1.面向?qū)ο蠼涌?br>

2.支持并發(fā)數(shù)配置

3.任務(wù)優(yōu)先級調(diào)度

4.任務(wù)依賴關(guān)系

5.線程優(yōu)先級配置

NSOperation簡介

在operation queue中,把每個并發(fā)任務(wù)都定義為一個operation,對應(yīng)的類名是NSOperation,NSOperation是一個抽象類,無法直接使用,它只定義了Operation的一些基本方法,我們需要創(chuàng)建一個基于他的子類或者使用系統(tǒng)預定于的子類,目前系統(tǒng)預定義了兩個子類:NSInvocationOperation和NSBlockOperation。

NSInvocationOperation

NSInvocationOperation是一個基于對象和selector的Operation,使用這個你只需要指定對象以及任務(wù)的selector,如果有必要,還可以設(shè)定傳遞的參數(shù)。

NSInvocationOperation *invacationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomethingWithObj:) object:obj];

當這個Operation完成后,你可以通過下面的方法獲得調(diào)用執(zhí)行后返回的結(jié)果對象。

id result = [invacationOperation result];

NSBlockOperation

如果不是在一個函數(shù)中執(zhí)行任務(wù),而是在一個block中執(zhí)行一個任務(wù)的話,這是我們就需要NSBlockOperation

NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

//Do?something?here.

}];

運行一個Operation

[Operation start] ;

start方法用來啟動一個Operation任務(wù)。同時,Operation提供一個main方法,你的所有任務(wù)都應(yīng)該在main中進行處理。默認的start方法中會先做出一些異常判斷然后直接調(diào)用main方法。如果需要自定義一個NSOperation必須重載main方法來執(zhí)行你所想要執(zhí)行的任務(wù)。

取消一個Operation

要取消一個Operation,要發(fā)送cancel消息:

[operation cancel];

當像一個Operation對象發(fā)送cancel消息之后,并不能保證這個Operation就一定能理科取消,這取決于你的main中對cancel的處理,,如果你在main中沒有對cancel進行任何處理的話,發(fā)送cancel消息是沒有任何效果的,為了讓Operation響應(yīng)cancel消息,那么你就要在main方法中一些適當?shù)牡胤绞謩优袛鄆sCancelled屬性,如果返回為YES的話,應(yīng)該釋放相關(guān)資源并立刻停止繼續(xù)執(zhí)行。

創(chuàng)建可并發(fā)的Operation

由于默認下Operation的start方法中直接調(diào)用了main方法,而main方法中會有比較耗時的處理任務(wù),如果我們在一段代碼中連續(xù)start了多個Operation的話,這個Operation都是阻塞地依次執(zhí)行完,因為第二個Operation必須等到第一個Operation執(zhí)行完start內(nèi)的main并返回,Operation默認都是不可并發(fā)的(使用了Operation Queue除外,Operation Queue會獨自管理自己的線程),因為默認Operation并不額外創(chuàng)建賢臣,我們可以通過OPeration的isConcurrent方法來判斷Operation是否是可并發(fā)的,如果要讓OPeration可并發(fā),我們需要讓main在單獨的線程執(zhí)行,并將isConcurrent返回YES。

這個方法是在每一個Operation中自己用NSThread來創(chuàng)建線程,當然,這樣的行為并不是如我們所愿的

@implementation MyOperation{

BOOL????????executing;

BOOL????????finished;

}

-?(BOOL)isConcurrent?{

returnYES;

}

-?(void)start?{

if([self?isCancelled])

{

[self?willChangeValueForKey:@"isFinished"];

finished?=?YES;

[self?didChangeValueForKey:@"isFinished"];

return;

}

[self?willChangeValueForKey:@"isExecuting"];

[NSThread?detachNewThreadSelector:@selector(main)?toTarget:self?withObject:nil];

executing?=?YES;

[self?didChangeValueForKey:@"isExecuting"];

}

-?(void)main?{

@try{

//?Do?some?work.

[self?willChangeValueForKey:@"isFinished"];

[self?willChangeValueForKey:@"isExecuting"];

executing?=?NO;

finished?=?YES;

[self?didChangeValueForKey:@"isExecuting"];

[self?didChangeValueForKey:@"isFinished"];

}

@catch(...)?{

//?Exception?handle.

}

}

@end

當你自定義了start或main方法時,一定要手動的調(diào)用一些KVO通知方法,以便讓對象的KVO機制可以正常運作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容