NSOperationQueue與GCD是伯仲之間嗎
事實(shí):GCD是面向底層的C語言的API一睁, NSOperationQueue是基于GCD面向OC的封裝
結(jié)果:
1)GCD執(zhí)行效率更高
2)GCD只支持FIFO的隊(duì)列冈闭,而NSOperationQueue可以通過設(shè)置最大并發(fā)數(shù)赚窃,設(shè)置優(yōu)先級(jí)册招,添加依賴關(guān)系等調(diào)整執(zhí)行順序
3)NSOperationQueue甚至可以跨隊(duì)列設(shè)置依賴關(guān)系,但是GCD只能通過設(shè)置串行隊(duì)列勒极,或者在隊(duì)列內(nèi)添加barrier(dispatch_barrier_async)任務(wù)是掰,才能控制執(zhí)行順序,較為復(fù)雜
- NSOperationQueue因?yàn)槊嫦驅(qū)ο螅灾С諯VO辱匿,可以監(jiān)測operation是否正在執(zhí)行(isExecuted)键痛、是否結(jié)束(isFinished)炫彩、是否取消(isCanceld)
NSOperationQueue的API
- start,開啟任務(wù),當(dāng)把NSOperation添加到NSOperationQueue中去后絮短,隊(duì)列會(huì)在操作中調(diào)用start方法江兢。這里沒有添加到NSOperationQueue中,手動(dòng)start丁频,默認(rèn)在主隊(duì)列中
//start 開啟任務(wù)划址,默認(rèn)主隊(duì)列
NSBlockOperation *operationOne = [NSBlockOperation blockOperationWithBlock:^{\
for (int i=0; i<3; i++) {
NSLog(@"=%@=====%d",[NSThread currentThread],i);
}
}];
[operationOne start];
- addOperation或者addOperationWithBlock , 只要是自己創(chuàng)建的隊(duì)列限府,就會(huì)在子線程中執(zhí)行,默認(rèn)并發(fā)痢缎,設(shè)置maxConcurrentOperationCount為 1 時(shí)是串行執(zhí)行
//主隊(duì)列
NSOperationQueue *mainqueue = [NSOperationQueue mainQueue];
//自己創(chuàng)建的隊(duì)列
NSOperationQueue *customQueue = [[NSOperationQueue alloc]init];
customQueue.maxConcurrentOperationCount = 2; //最大并發(fā)數(shù)
//只要是自己創(chuàng)建的隊(duì)列胁勺,就會(huì)在子線程中執(zhí)行,默認(rèn)并發(fā)独旷,設(shè)置maxConcurrentOperationCount時(shí)是串行執(zhí)行
[customQueue addOperationWithBlock:^{
//向隊(duì)列中添加block異步任務(wù)
for (int i=3; i<6; i++) {
NSLog(@"=%@=====%d",[NSThread currentThread],i);
}
}];
[customQueue addOperationWithBlock:^{
//向隊(duì)列中添加block異步任務(wù)
for (int i=6; i<9; i++) {
NSLog(@"=%@=====%d",[NSThread currentThread],i);
}
}];
//添加 NSInvocationOperation
[customQueue addOperation:[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationOperationDeal) object:nil]];
- 隊(duì)列控制API
//將隊(duì)列中任務(wù)暫停
customQueue.suspended = YES;
//將隊(duì)列中任務(wù)恢復(fù)執(zhí)行
customQueue.suspended = NO;
//取消隊(duì)列中的所有任務(wù)
[customQueue cancelAllOperations];
- addDependency 添加依賴署穗,removeDependency刪除依賴,
//任務(wù)之間添加依賴嵌洼,比如當(dāng)前一個(gè)任務(wù)的返回結(jié)果 是 后一個(gè)任務(wù)的所需元素時(shí)
NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
//計(jì)算出小明的臉部數(shù)據(jù)
}];
NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{
//計(jì)算出小明的頭圍數(shù)據(jù)
}];
NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{
// 制作出小明的頭部模型
}];
[blockOp3 addDependency:blockOp1];
[blockOp3 addDependency:blockOp2]; //blockOp3的操作依賴于 1 和 2 的結(jié)果
[customQueue addOperations:@[blockOp1,blockOp2,blockOp3] waitUntilFinished:NO];
- setQueuePriority案疲,設(shè)置優(yōu)先級(jí), 當(dāng)你添加一個(gè)操作到一個(gè)隊(duì)列時(shí),在對(duì)操作調(diào)用start之前麻养,NSOperationQueue會(huì)瀏覽所有的操作褐啡,具有較高優(yōu)先級(jí)的操作會(huì)優(yōu)先執(zhí)行,具有相同優(yōu)先級(jí)的操作會(huì)按照添加到隊(duì)列中順序執(zhí)行鳖昌。
[a setQueuePriority:NSOperationQueuePriorityVeryLow];
一共有四個(gè)優(yōu)先級(jí):
NSOperationQueuePriorityLow备畦,
NSOperationQueuePriorityNormal,
NSOperationQueuePriorityHigh许昨,
NSOperationQueuePriorityVeryHigh
- setCompletionBlock 設(shè)置完成回調(diào)
[blockOp2 setCompletionBlock:^{
//blockOp2任務(wù)執(zhí)行完成懂盐,此block在主線程執(zhí)行
}];
小結(jié)
1、實(shí)際項(xiàng)目開發(fā)中糕档,很多時(shí)候只是會(huì)用到異步操作莉恼,不會(huì)有特別復(fù)雜的線程關(guān)系管理,所以蘋果推崇的且優(yōu)化完善速那、運(yùn)行快速的GCD是首選
2俐银、如果涉及到類似多線程并發(fā)下載,這種多任務(wù)還要控制任務(wù)進(jìn)度的情況琅坡,可能就要考慮使用易于管理的NSOperationQueue了悉患,關(guān)于自定義NSOperation的內(nèi)容,后續(xù)我會(huì)另寫一篇文章的榆俺,繼續(xù)學(xué)習(xí)
3售躁、另外不論是GCD還是NSOperationQueue坞淮,我們接觸的都是任務(wù)和隊(duì)列,都沒有直接接觸到線程這個(gè)東東陪捷,事實(shí)上線程管理也的確不需要我們操心回窘,系統(tǒng)對(duì)于線程的創(chuàng)建,調(diào)度管理和釋放都做得很好市袖。但是有一個(gè)線程類NSThread可以滿足我們對(duì)于線程的好奇心啡直,但是NSThread需要我們自己去管理線程的生命周期,還要考慮線程同步苍碟、加鎖問題酒觅,造成一些性能上的開銷
附圖,這張圖如此之精辟微峰,讓我久久挪不開眼睛