NSOperationQueue、NSOperation及其子類介紹

上篇文章寫到GCD,GCD的優(yōu)點(diǎn)是我們只需要定義想要執(zhí)行的任務(wù)并追加到適當(dāng)?shù)腄ispatch Queue中,GCD負(fù)責(zé)生成線程、計(jì)劃執(zhí)行任務(wù)并管理線程的生命周期,其線程管理是作為系統(tǒng)的一部分來實(shí)現(xiàn)的,因此可統(tǒng)一管理,所以效率很高,而且形式上十分簡潔。

GCD看似很完美了,但是GCD是基于C語言開發(fā)的,而NSOperation是基于GCD且面向?qū)ο蟮募夹g(shù),比GCD多了一些簡單實(shí)用的功能。雖然NSOperation會增加額外的開銷,但是更加靈活。NSOperation對應(yīng)GCD的任務(wù),NSOperationQueue對應(yīng)GCD的隊(duì)列。

NSOperation

NSOperation是一個抽象類,我們創(chuàng)建需要執(zhí)行的任務(wù)時,需要使用其子類。Apple為我們定義了兩個NSOperation的子類:NSInvocationOperation和NSBlockOperation,另外我們可以自定義NSOperation的子類。

NSOperationQueue

有兩種NSOperationQueue:

主隊(duì)列:通過下面方法獲取,放到主隊(duì)列的任務(wù)在主線程執(zhí)行。

NSOperationQueue*queue = [NSOperationQueuemainQueue];

非主隊(duì)列

NSOperationQueue*queue = [[NSOperationQueuealloc]init];

非主隊(duì)列既可以并發(fā)執(zhí)行任務(wù)也可以串行執(zhí)行任務(wù),通過設(shè)置最大并發(fā)數(shù)來控制。最大并發(fā)數(shù)默認(rèn)為-1,表示不受限制,如果最大并發(fā)數(shù)為1則是串行隊(duì)列。非主隊(duì)列無論是并發(fā)隊(duì)列還是串行隊(duì)列都不在主線程中執(zhí)行。

NSOperation可以調(diào)用start方法來執(zhí)行任務(wù),而不用加入到NSOperationQueue中,但是該任務(wù)將會在當(dāng)前線程同步執(zhí)行。

NSInvocationOperation

NSInvocationOperation *io =?[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest) object:nil];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperation:io];

- (void)invocationTest {

for(int i =0; i <100; i++) {

NSLog(@"mainThread: %@, currentThread: %@", [NSThreadmainThread], [NSThreadcurrentThread]);

}

}

NSBlockOperation

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^ {

for(int i =0; i <100; i++) {

NSLog(@"%@",[NSThread currentThread]);

}

}];

[queue addOperation:bo];

自定義非并發(fā)的NSOperation子類:

我們要自定義初始化方法,并重寫- (void)main {};方法,在此方法中需要能相應(yīng)取消時間。

其余方法:

NSBlockOperation的addExecutionBlock方法:

NSBlockOperation *blockOperation = [NSBlockOperationblock OperationWithBlock:^{

NSLog(@"block1 : currentThread: %@", [NSThread currentThread]);

sleep(3);

}];

[blockOperation addExecutionBlock:^{

NSLog(@"block2 : currentThread: %@", [NSThread currentThread]);

sleep(3);

}];

[blockOperation addExecutionBlock:^{

NSLog(@"block3 : currentThread: %@", [NSThread currentThread]);

sleep(3);

}];

[blockOperation start];

結(jié)果:Block1是在主線程中執(zhí)行的,block2和block3不是。

添加依賴:

[io addDependency:bo];

io會在bo執(zhí)行完后執(zhí)行,不同隊(duì)列的operation之間可以添加依賴。

可通過下面方法執(zhí)行operation完畢后的操作。

io.completionBlock= ^{

NSLog(@"finish");

};

我們經(jīng)常需要在非主線程完成后回到主線程刷新UI:

NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^ {

for(inti =0; i <100; i++) {

NSLog(@"%@",[NSThread currentThread]);

}

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

NSLog(@"=====%@",[NSThreadcurrentThread]);

}];;

}];

暫停任務(wù):

queue.suspended = YES;

恢復(fù)任務(wù):

queue.suspended=NO;

取消所有任務(wù),一旦取消不可逆

[queue cancelAllOperations];

暫停和取消只能暫停或取消處于等待狀態(tài)的任務(wù),不能暫停或取消正在執(zhí)行中的任務(wù)


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

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

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