多線程 NSOperation

+++
Categories = ["iOS",]
Tags = ["iOS","NSOperation"]
date = "2014-11-17T14:01:09+08:00"
title = "多線程 NSOperation"

+++

NSOperation介紹

NSOperation是一個(gè)抽象的基類,表示一個(gè)獨(dú)立的計(jì)算單元,可以為子類提供有用且線程安全的建立狀態(tài),優(yōu)先級(jí),依賴和取消等操作。系統(tǒng)已經(jīng)給我們封裝了NSBlockOperation和NSInvocationOperation這兩個(gè)實(shí)體類。

  1. 使用NSOperation處理多線程時(shí),就是將“操作”添加到隊(duì)列中。
  2. NSOperation是一個(gè)抽象類,不能直接使用(方法沒(méi)有實(shí)現(xiàn)),約束子類都具有共同的屬性和方法。
  3. NSOperation的子類:NSInvocationOperation、NSBlockOperation、自定義NSOperation。
  4. 通過(guò)NSOperationQueue可以創(chuàng)建并發(fā)隊(duì)列,獲取主隊(duì)列,獲取當(dāng)前隊(duì)列。

NSOperation定義

- (void)start;
- (void)main;

@property (readonly, getter=isCancelled) BOOL cancelled;
- (void)cancel;

@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below
@property (readonly, getter=isAsynchronous) BOOL asynchronous NS_AVAILABLE(10_8, 7_0);
@property (readonly, getter=isReady) BOOL ready;

- (void)addDependency:(NSOperation *)op;
- (void)removeDependency:(NSOperation *)op;

@property (readonly, copy) NSArray *dependencies;

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
    NSOperationQueuePriorityVeryLow = -8L,
    NSOperationQueuePriorityLow = -4L,
    NSOperationQueuePriorityNormal = 0,
    NSOperationQueuePriorityHigh = 4,
    NSOperationQueuePriorityVeryHigh = 8
};

@property NSOperationQueuePriority queuePriority;

@property (copy) void (^completionBlock)(void) NS_AVAILABLE(10_6, 4_0);

- (void)waitUntilFinished NS_AVAILABLE(10_6, 4_0);

@property double threadPriority NS_DEPRECATED(10_6, 10_10, 4_0, 8_0);

@property NSQualityOfService qualityOfService NS_AVAILABLE(10_10, 8_0);

@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);
狀態(tài)

NSOperation提供了ready cancelled executing finished這幾個(gè)狀態(tài)變化,我們的開(kāi)發(fā)也是必須處理自己關(guān)心的其中的狀態(tài)。這些狀態(tài)都是基于keypath的KVO通知決定,所以在你手動(dòng)改變自己關(guān)心的狀態(tài)時(shí),請(qǐng)別忘了手動(dòng)發(fā)送通知。這里面每個(gè)屬性都是相互獨(dú)立的,同時(shí)只可能有一個(gè)狀態(tài)是YES。finished這個(gè)狀態(tài)在操作完成后請(qǐng)及時(shí)設(shè)置為YES,因?yàn)镹SOperationQueue所管理的隊(duì)列中,只有isFinished為YES時(shí)才將其移除隊(duì)列,這點(diǎn)在內(nèi)存管理和避免死鎖很關(guān)鍵。

依賴

NSOperation中我們可以為操作分解為若干個(gè)小的任務(wù),通過(guò)添加他們之間的依賴關(guān)系進(jìn)行操作,我們可以直接調(diào)用 - (void)addDependency:(NSOperation*)op; 這個(gè)方法添加依賴.依賴關(guān)系可以跨操作隊(duì)列,操作不再同一個(gè)隊(duì)列中,依賴關(guān)系也是存在的。

執(zhí)行

執(zhí)行一個(gè)operation有兩種方法,第一種是自己手動(dòng)的調(diào)用start這個(gè)方法,這種方法調(diào)用會(huì)在當(dāng)前調(diào)用的線程進(jìn)行同步執(zhí)行,所以在主線程里面自己一定要小心的調(diào)用,不然就會(huì)把主線程給卡死。第二種是將operation添加到operationQueue中去,這個(gè)也是我們用得最多的也是提倡的方法。NSOperationQueue會(huì)在我們添加進(jìn)去operation的時(shí)候盡快進(jìn)行執(zhí)行。當(dāng)然如果 NSOperationQueue的maxConcurrentOperationCount 如果設(shè)置為1的話,進(jìn)相當(dāng)于FIFO了。

GCD和NSOperation的對(duì)比

  1. GCD
GCD是iOS4.0推出的,主要針對(duì)多核CPU做了優(yōu)化,是C語(yǔ)言的技術(shù)。 

GCD是將任務(wù)(block)添加到隊(duì)列(串行/并行/全局/主隊(duì)列),并且以同步/異步的方式執(zhí)行任務(wù)的函數(shù)。

GCD提供給了一些NSOperation不具備的功能:①一次性執(zhí)行;②延遲執(zhí)行;③調(diào)度組。
  1. NSOperation
NSOperation是iOS2.0推出的,iOS4.0之后重寫(xiě)了NSOperation。

NSOperation將操作(異步的任務(wù))添加到隊(duì)列(并發(fā)隊(duì)列),就會(huì)執(zhí)行指定操作的函數(shù)。

NSOperation里提供的方便的操作:①最大并發(fā)數(shù);②隊(duì)列的暫停/繼續(xù);③取消所有的操作;④指定操作之間的依賴關(guān)系(GCD可以用同步實(shí)現(xiàn))。
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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