NSOperation

簡介

  • NSOperation的作用

    • NSOperation和NSOperationQueue配合使用也能實現多線程編程
  • NSOperation和NSOperationQueue實現多線程的具體步驟

    • 先將需要執行的操作封裝到一個NSOperation對象中
    • 然後將NSOperation對象添加到NSOperationQueue中
    • 系統會自動將NSOperationQueue中的NSOperation取出來
    • 將取出的NSOperation封裝的操作放到一條新線程中執行

NSOperation的子類

  • NSOperation是個抽象類,並不具備封裝操作的能力,必須使用它的子類

  • 使用NSOperation子類的方式有3種

    • NSInvocationOperation
    • NSBlockOperation
    • 自定義子類繼承NSOperation,實現內部相應的方法

NSInvocationOperation

  • 創建NSInvocationOperation對象

    • (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
  • 調用start方法開始執行操作

    • (void)start;
    • 一旦執行操作,就會調用target的sel方法
  • 注意

    • 默認情況下,調用了start方法後並不會開一條新線程去執行操作,而是在當前線程同步執行操作
      只有將NSOperation放到一個NSOperationQueue中,纔會異步執行操作

NSBlockOperation

  • 創建NSBlockOperation對象

    • (id)blockOperationWithBlock:(void (^)(void))block;
  • 通過addExecutionBlock:方法添加更多的操作

    • (void)addExecutionBlock:(void (^)(void))block;
  • 注意:只要NSBlockOperation封裝的操作數 > 1,就會異步執行操作

NSOperationQueue

  • NSOperationQueue的作用

    • NSOperation可以調用start方法來執行任務,但默認是同步執行的
    • 如果將NSOperation添加到NSOperationQueue(操作隊列)中,系統會自動異步執行NSOperation中的操作
  • 添加操作到NSOperationQueue中

    • (void)addOperation:(NSOperation *)op;
    • (void)addOperationWithBlock:(void (^)(void))block;

最大併發數

  • 什麼是併發數

    • 同時執行的任務數
    • 比如,同時開3個線程執行3個任務,併發數就是3
  • 最大併發數的相關方法

    • (NSInteger)maxConcurrentOperationCount;
    • (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

隊列的取消、暫停、恢復

  • 取消隊列的所有操作

    • (void)cancelAllOperations;
    • 提示:也可以調用NSOperation的- (void)cancel方法取消單個操作
  • 暫停和恢復隊列

    • (void)setSuspended:(BOOL)b; // YES代表暫停隊列,NO代表恢復隊列
    • (BOOL)isSuspended;

操作依賴

  • NSOperation之間可以設置依賴來保證執行順序

    • 比如一定要讓操作A執行完後,才能執行操作B,可以這麼寫
    • [operationB addDependency:operationA]; // 操作B依賴於操作A
  • 可以在不同queue的NSOperation之間創建依賴關係

操作的監聽

  • 可以監聽一個操作的執行完畢
    • (void (^)(void))completionBlock;
    • (void)setCompletionBlock:(void (^)(void))block;

自定義NSOperation

  • 自定義NSOperation的步驟很簡單

    • 重寫- (void)main方法,在裏面實現想執行的任務
  • 重寫- (void)main方法的注意點

    • 自己創建自動釋放池(因爲如果是異步操作,無法訪問主線程的自動釋放池)
    • 經常通過- (BOOL)isCancelled方法檢測操作是否被取消,對取消做出響應

線程間通信

-(void)download
{    
    // 1.開子線程下載圖片
    // 1.1 非主隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    // 1.2 封裝操作
    NSBlockOperation *download = [NSBlockOperation blockOperationWithBlock:^{

        NSURL *url = [NSURL URLWithString:@"download url"];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:imageData];

        NSLog(@"download---%@",[NSThread currentThread]);

        // 3.更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
            NSLog(@"UI---%@",[NSThread currentThread]);
        }];

    }];

    // 2.添加操作到隊列
    [queue addOperation:download];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章