GCD和NSOperation NSOperationQueue的比較
- GCD是c語(yǔ)言實(shí)現(xiàn)的一套API,是一種輕量級(jí)的實(shí)現(xiàn)多線程的方法。隊(duì)列中執(zhí)行的是由block構(gòu)成的任務(wù)。
-
優(yōu)點(diǎn)
1.在多核CPU上線程切換時(shí)間快,效率相對(duì)高
2.結(jié)合block使用比較高效
-
缺點(diǎn)
1.無(wú)法停止加入隊(duì)列的block
2.只能區(qū)分不同任務(wù)隊(duì)列的優(yōu)先級(jí),區(qū)分block任務(wù)的優(yōu)先級(jí)不易
3.設(shè)置依賴關(guān)系麻煩
-
-
NSOperation和NSOperationQueues是面向?qū)ο蟮姆绞健?/p>
-
優(yōu)點(diǎn)
1.可以隨時(shí)取消準(zhǔn)備要執(zhí)行的任務(wù)(任務(wù)開始之后就無(wú)法阻止了)
2.可以方便設(shè)置兩個(gè)操作的依賴關(guān)系
3.可以應(yīng)用KVO,去監(jiān)聽(tīng)一個(gè)操作是否取消或者完成
4.可以設(shè)置操作的優(yōu)先級(jí),是隊(duì)列中的任務(wù)分優(yōu)先級(jí)的執(zhí)行
-
缺點(diǎn)
1.性能方面遜于GCD
-
NSOperation的API使用方法
1.繼承NSOperation
2.重寫“main”函數(shù)
3.在“main”函數(shù)中建立“autoreleasepool”(你不能獲取主線程的自動(dòng)釋放池)
4.把代碼放入“autoreleasepool”
方法:
- 取消 cancel:
- [test_operation cancel];
- 開始 start
- [test_operation start];
- 如果在隊(duì)列中添加一個(gè)操作,然后這個(gè)隊(duì)列執(zhí)行start, 然后這個(gè)操作的main函數(shù)會(huì)執(zhí)行相應(yīng)的操作。 如果你在NSOperarion的實(shí)例上執(zhí)行一個(gè)操作,沒(méi)有加入隊(duì)列,那么操作會(huì)在main loop中執(zhí)行
- 依賴 dependency
- [test1Op addDependency: test2Op];
- [test1Op removeDependency: test2Op]
- 優(yōu)先級(jí)
- [test1Op setQueuePriority:NSOperationQueuePriorityVeryLow]
優(yōu)先級(jí)可以設(shè)定的值
NSOperationQueuePriorityLow
NSOperationQueuePriorityNormal
NSOperationQueuePriorityHigh
NSOperationQueuePriorityVeryHigh
當(dāng)隊(duì)列中有多個(gè)操作時(shí),執(zhí)行順序會(huì)按照優(yōu)先級(jí)排序,如果兩個(gè)優(yōu)先級(jí)相同,則按添加多隊(duì)列中的順序進(jìn)行執(zhí)行。
- Completion block
- 如果你有一些事情要在操作執(zhí)行完畢后做, 你可以把這些放入block,并且傳入這個(gè)方法中。注:不會(huì)確保這個(gè)block在主線程執(zhí)行。[test1Op setCompletionBlock: ^{ "block" }];
注意的點(diǎn)
- 如果你要給操作傳入一些值或者指針,最好的方法是創(chuàng)建你自己的初始化方法。
- 如果你的操作有返回值或者對(duì)象,好的方式是聲明代理方法。通常你想在主線程回調(diào)代理方法。
- 你不可以重新給操作排隊(duì),一旦操作加入隊(duì)列,你就放棄了所有權(quán)。如果你想再次使用相同的操作,你應(yīng)該創(chuàng)建一個(gè)新實(shí)例
- 如果你要取消一個(gè)操作,他不會(huì)馬上發(fā)生。他會(huì)在未來(lái)檢查 isCancelled == YES 的時(shí)候被調(diào)用,否則,他會(huì)一直執(zhí)行直到完成操作。
- 無(wú)論操作是否成功完成,或者是被取消。 isFinished都將返回YES。
NSOperationQueue API使用
NSOperationQueue 不需要你繼承,或者重載任何方法。你直接創(chuàng)建一個(gè)對(duì)象。最好是給你的隊(duì)列起一個(gè)名字以方便你運(yùn)行的時(shí)候識(shí)別以及調(diào)試。
方法及屬性:
- 并行操作:一個(gè)隊(duì)列有好多個(gè)線程,隊(duì)列中的每個(gè)操作在自己的線程中運(yùn)行。
- 并行操作的最大數(shù):
- myQueue.MaxConcurrentOperationCount = 3;
- 如果要恢復(fù)到默認(rèn)值 myQueue.MaxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
- 添加操作:
- [myQueue addOperation: downloadOp];
- 未執(zhí)行的操作:
- NSArray *active_and_pending_operations = myQueue.operations;
- NSInteger count_of_operations = myQueue.operationCount;
- 暫停/恢復(fù)隊(duì)列:
- [myQueue setSuspended:YES];
- [myQueue setSuspended:NO];
- 取消操作:
- [myQueue cancelAllOperations];
- 建立對(duì)Block的操作:
建立block的例子:
__weak MyViewController *weakSelf = self;
// Add an operation as a block to a queue
[myQueue addOperationWithBlock: ^ {
NSURL *aURL = [NSURL URLWithString:@"http://www.somewhere.com/image.png"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];
UIImage *image = nil;
If (data)
image = [UIImage imageWithData:data];
// Update UI on the main thread.
[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
weakSelf.imageView.image = image;
}];