NSOperation 詳解

定義:NSOperation,OC對象,內部封裝了GCD,可以實現管理隊列的操作,如果開發中不需要管理這些隊列,那麼使用GCD就足夠了

    

//操作 (NSOperation是抽象類,不能直接調用,而是用兩個子類)


1、NSInvocationOperation

2、NSBlockOperation 

//也可以通過重寫NSOperation的main方法來達到自定義操作


注意: NSBlockOperaion 如果追加了任務,直接啓動操作/或者將操作添加到主隊列,都不能保證操作中的任務是在主線程執行!任務在哪條線程執行不確定!開發中要避免往 NSBlockOperation 中追加任務!放到非主隊列中執行沒有問題!


以下是相關方法

- (void)start; //在當前任務狀態和依賴關係合適的情況下,啓動NSOperation的main方法任務,需要注意缺省實現只是在當前線程運行。如果需要併發執行,子類必須重寫這個方法,並且使 - (BOOL)isConcurrent 方法返回YES

- (void)main; //定義NSOperation的主要任務代碼

- (BOOL)isCancelled; //當前任務狀態是否已標記爲取消

- (void)cancel; //取消當前NSOperation任務,實質是標記isCancelled狀態

- (BOOL)isExecuting; //NSOperation任務是否在運行

- (BOOL)isFinished; //NSOperation任務是否已結束

NSOperation其它常用方法,包括依賴關係:

- (BOOL)isReady; //是否能準備運行,這個值和任務的依賴關係相關

- (void)addDependency:(NSOperation *)op; //加上任務的依賴,也就是說依賴的任務都完成後,才能執行當前任務

- (void)removeDependency:(NSOperation *)op; //取消任務的依賴,依賴的任務關係不會自動消除,必須調用該方法

- (NSArray *)dependencies; //得到所有依賴的NSOperation任務

以及用於任務同步:

- (void)waitUntilFinished; //阻塞當前線程,直到該NSOperation結束。可用於線程執行順序的同步

- (void)setCompletionBlock:(void (^)(void))block; //設置NSOperation結束後運行的block代碼,由於NSOperation有可能被取消,所以這個block運行的代碼應該和NSOperation的核心任務無關。

 

除了繼承NSOperation來實現併發代碼,通常更簡便的辦法是使用它的兩個子類NSInvocationOperationNSBlockOperation,然後加入到NSOperationQueue執行隊列中去運行。部分示例代碼如下:

NSInvocationOperation *opA = [[NSInvocationOperationalloc]initWithTarget:self selector:@selector(operate) object:nil];

NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{

        [self operate];

    }];

- (void)operate

{

  //thread loop

  while (condition)

  {

    //....

  }

}

NSOperationQueue *queue = [[NSOperationQueueallocinit];

queue.maxConcurrentOperationCount = 2; //設置最大併發執行數,如果爲1則同時只有一個併發任務在運行,可控制順序執行關係

[queue addOperation:opA]; //加入到執行隊列中,如果isReady則開始執行

[queue addOperation:opB]; //同上,需要注意這時opA和opB是在併發運行

[queue waitUntilAllOperationsAreFinished]; //當前線程等待,直到opA和opB都執行結束

如果要求opB在opA執行完成後纔開始執行,需要加上依賴關係即可:

[opB addDependency:opA];

當然也可以使用同步方法waitUntilFinished,在前面的例子中加入:

NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{

   [opA waitUntilFinished]; //opB線程等待直到opA執行結束(正常結束或被取消)

        [self operate];

    }];

建立依賴關係或等待關係,一定要出現避免循環依賴或循環等待,否則就會造成線程死鎖。

最後看看NSOperationQueue的其它常用方法:

- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait; //批量加入執行operation,wait標誌是否當前線程等到所有operation結束

- (void)addOperationWithBlock:(void (^)(void))block; //相當於加入一個NSBlockOperation執行任務

- (NSArray *)operations; //返回已加入執行operation的數組,當某個operation結束後會自動從這個數組清除

- (NSUInteger)operationCount //返回已加入執行operation的數目

- (void)setSuspended:(BOOL)b; //是否暫停將要執行的operation,但不會暫停已開始的operation

- (BOOL)isSuspended; //返回暫停標誌

- (void)cancelAllOperations; //取消所有operation的執行,實質是調用各個operation的cancel方法

+ (id)currentQueue; //返回當前NSOperationQueue,如果當前線程不是在NSOperationQueue上運行則返回nil

+ (id)mainQueue; //返回主線程的NSOperationQueue,缺省總是有一個queue


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章