NSOperation 抽象類


  • NSOperation
     是一個"抽象類",不能直接使用web

  • 抽象類的用處是定義子類共有的屬性和方法數據結構

  • 在蘋果的頭文件中,有些抽象類和子類的定義是在同一個頭文件中的併發

  • 子類:框架

    • NSInvocationOperation (調用)異步

    • NSBlockOperation (塊)函數

  • NSOperationQueue 隊列學習

已經學習過的抽象類

  • UIGestureRecognizeratom

  • CAAnimationspa

  • CAPropertyAnimation線程

基本演練

NSInvocationOperation

start

- (void)opDemo1 {
   NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];    // start方法 會在當前線程執行 @selector 方法
   [op start];
}

- (void)downloadImage:(id)obj {    NSLog(@"%@ %@", [NSThread currentThread], obj);
}

添加到隊列

- (void)opDemo2 {
   NSOperationQueue *q = [[NSOperationQueue alloc] init];

   NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"queue"];

   [q addOperation:op];
}

添加多個操做

- (void)opDemo3 {
   NSOperationQueue *q = [[NSOperationQueue alloc] init];    for (int i = 0; i < 10; ++i) {
       NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@(i)];

       [q addOperation:op];
   }
}

執行效果:會開啓多條線程,並且不是順序執行。與GCD中併發隊列&異步執行效果同樣!

結論,在 NSOperation 中:

NSBlockOperation

- (void)opDemo4 {
   NSOperationQueue *q = [[NSOperationQueue alloc] init];

   NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"%@", [NSThread currentThread]);
   }];

   [q addOperation:op];
}

使用 block 來定義操做,全部的代碼寫在一塊兒,更簡單,便於維護!

更簡單的,直接添加 Block

- (void)opDemo5 {
   NSOperationQueue *q = [[NSOperationQueue alloc] init];    for (int i = 0; i < 10; ++i) {
       [q addOperationWithBlock:^{            NSLog(@"%@ %d", [NSThread currentThread], i);
       }];
   }
}

向隊列中添加不一樣的操做

- (void)opDemo5 {
   NSOperationQueue *q = [[NSOperationQueue alloc] init];    for (int i = 0; i < 10; ++i) {
       [q addOperationWithBlock:^{            NSLog(@"%@ %d", [NSThread currentThread], i);
       }];
   }

   NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"block %@", [NSThread currentThread]);
   }];
   [q addOperation:op1];

   NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"invocation"];
   [q addOperation:op2];
}

線程間通信

- (void)opDemo6 {
   NSOperationQueue *q = [[NSOperationQueue alloc] init];

   [q addOperationWithBlock:^{        NSLog(@"耗時操做 %@", [NSThread currentThread]);        // 主線程更新 UI
       [[NSOperationQueue mainQueue] addOperationWithBlock:^{            NSLog(@"更新 UI %@", [NSThread currentThread]);
       }];
   }];
}


高級演練

全局隊列

/// 全局操做隊列,統一管理全部的異步操做@property (nonatomic, strong) NSOperationQueue *queue;

- (NSOperationQueue *)queue {    if (_queue == nil) {
       _queue = [[NSOperationQueue alloc] init];
   }    return _queue;
}

最大併發操做數

/// MARK: - 最大併發操做數- (void)opDemo1 {    // 設置同時併發操做數
   self.queue.maxConcurrentOperationCount = 2;    NSLog(@"start");    for (int i = 0; i < 10; ++i) {
       NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
           [NSThread sleepForTimeInterval:1.0];            NSLog(@"%@ %d", [NSThread currentThread], i);
       }];

       [self.queue addOperation:op];
   }
}

暫停 & 繼續

/// MARK: - 暫停 & 繼續- (IBAction)pauseAndResume {    if (self.queue.operationCount == 0) {        NSLog(@"沒有操做");        return;
   }    // 暫停或者繼續
   self.queue.suspended = !self.queue.isSuspended;    if (self.queue.isSuspended) {        NSLog(@"暫停 %tu", self.queue.operationCount);
   } else {        NSLog(@"繼續 %tu", self.queue.operationCount);
   }
}

取消所有操做

/// MARK: - 取消全部操做- (IBAction)cancelAll {    if (self.queue.operationCount == 0) {        NSLog(@"沒有操做");        return;
   }    // 取消對列中的全部操做,一樣不會影響到正在執行中的操做!
   [self.queue cancelAllOperations];    NSLog(@"取消所有操做 %tu", self.queue.operationCount);
}

依賴關係

/// MARK: - 依賴關係- (void)dependency {

   NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"登陸 %@", [NSThread currentThread]);
   }];
   NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"付費 %@", [NSThread currentThread]);
   }];
   NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"下載 %@", [NSThread currentThread]);
   }];
   NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"通知用戶 %@", [NSThread currentThread]);
   }];

   [op2 addDependency:op1];
   [op3 addDependency:op2];
   [op4 addDependency:op3];    // 注意不要循環依賴//    [op1 addDependency:op4];

   [self.queue addOperations:@[op1, op2, op3] waitUntilFinished:NO];
   [[NSOperationQueue mainQueue] addOperation:op4];    NSLog(@"come here");
}


與 GCD 的對比

相關文章
相關標籤/搜索