多線程之NSOperations和NSOperationQueues

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

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

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