首页 > 学院 > 开发设计 > 正文

IOS开发之NSOperation

2019-11-14 18:36:08
字体:
来源:转载
供稿:网友

NSOperation 抽象类

  • NSOperation 是一个抽象类,不能直接使用
  • 抽象类的用处是定义子类共有的属性和方法
  • 在苹果的头文件中,有些抽象类和子类的定义是在同一个头文件中的
  • 子类:
    • NSInvocationOperation (调用)
    • NSBlockOperation (块)
  • NSOperationQueue 队列

已经学习过的抽象类

  • UIGestureRecognizer
  • CAAnimation
  • CAPRopertyAnimation

基本演练

NSInvocationOperation

start

  • 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 中:

  • 操作 -> 异步执行的任务
  • 队列 -> 全局队列

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];}
  • 可以向 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");}

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表