NSOperation
是一個抽象類,不能直接使用
NSInvocationOperation
(調用)NSBlockOperation
(塊)NSOperationQueue
隊列UIGestureRecognizer
CAAnimation
CAPropertyAnimation
start
方法 會在當前線程執行 @selector
方法- (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); }
異步執行
selector
方法- (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 中:異步
- (void)opDemo4 { NSOperationQueue *q = [[NSOperationQueue alloc] init]; NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@", [NSThread currentThread]); }]; [q addOperation:op]; }
使用 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]; }
NSOperationQueue
中添加任意 NSOperation
的子類- (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"); }