美文网首页
NSOperation

NSOperation

作者: 鐧箪 | 来源:发表于2019-06-03 09:24 被阅读0次
NSOperation 与 NSOperationQueue是什么?
@interface NSOperation : NSObject
@interface NSOperationQueue : NSObject

NSOperationNSOperationQueue 是系统给我提供的一套多线程API 它们是基于GCD 更高层次的封装 完全面向对象。 相对于C语言的API 使用更加方便 可读性也更高。

NSOperation 与 GCD比较有哪些优势?
  1. 基于GCD的封装 可读性强 使用起来方便
    2.可以添加依赖 方便控制执行顺序
    3.可以设定执行的优先级
    4.可以更方便的取消一个操作的执行
    5.可以使用KVO观察任务的执行状态

与GCD相同 它也具备 任务 队列的概念

NSOperation

苹果框架使用了大量的抽象思想 NSOperation 也不例外 我们不能直接使用 NSOperation 需要用系统提供的的子类 NSBlockOperationNSInvocationOperation 或 继承来创建 NSOperation 的子类来使用

来看下 抽象类 NSOperation

- (void)start;  
- (void)main;
@property (readonly, getter=isCancelled) BOOL cancelled;
- (void)cancel;
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below
@property (readonly, getter=isAsynchronous) BOOL asynchronous API_AVAILABLE(macos(10.8), ios(7.0), watchos(2.0), tvos(9.0));
@property (readonly, getter=isReady) BOOL ready;

我的天呐 子类可以使用这么多属性 它们都是用来干啥的啊!

isReady -> isExecuting -> isFinished

isReady 是否准备好 返回YES表示准备好被执行
isExecuting 是否正在执行 返回YE表示正在执行
isFinished 是否执行完毕 返回YES表示操作成功 或 被取消
isConcurrent、isAsynchronous 定义并发操作队列 返回YES告诉外界这是个并发的

NSOperation 默认是非并发的 你把operation 放到那个线程 它会一直阻塞住那个线程 直到 operationfinished 变为YES 才会继续向下执行 如果是非并发的 子需要自定义NSOperation的时候 重写他的 main方法 即可 。

-(void)start {
    NSLog(@"开始了");
}

-(void)main {
    NSLog(@"isExecuting====%d",self.isExecuting);
    if (!self.isCancelled) {
        sleep(10);
        NSLog(@"执行完啦!");
    }
    
} 
GlobalOperation * operation =  [[GlobalOperation alloc] init];
 [operation start];
 NSLog(@"我等的好累啊");
开始了
我等的好累啊

可以看出 重载start方法后 main不会执行 start方法是开启手动管理 operation 可以异步执行来使用 同步执行 重写main 即可

-(void)main {
    NSLog(@"isExecuting====%d",self.isExecuting);
    if (!self.isCancelled) {
        sleep(10);
        NSLog(@"执行完啦!");
    }
    
} 
GlobalOperation * operation =  [[GlobalOperation alloc] init];
 [operation start];
 NSLog(@"我等的好累啊");
执行完啦!
我等的好累啊

可以看到 等待10秒后 执行 后面的语句 说明operation 默认非并发 同步执行

下面我们来看 并发执行 重写start方法 手动控制 operation 的生命周期

start 并发必须重写 来替换原先的操作 手动执行一个操作 调用start方法 不要调用[supper start]

isExecuting 和 isFinish 并发队列 手动控制 需要知道当前的状态信息 通过KVO来监听当前状态的执行情况

isConcurrent、isAsynchronous 推荐重新第二个 返回YES 告诉外界这是个并发的

// 因为父类的属性是Readonly的,重载时如果需要setter的话则需要手动合成。
@synthesize finished = _finished, executing = _executing;

-(void)start {
   
    if (self.isCancelled) {
        self.finished = YES;
        return;
    }
    self.executing = YES;
    
    dispatch_async(dispatch_queue_create("yb", DISPATCH_QUEUE_CONCURRENT), ^{
        sleep(10);
        NSLog(@"执行完啦!");
        self.executing = NO;
        self.finished = YES;
    });

}
- (void)cancel {
    [super cancel];
    
    // 如果正在执行中则表示已经start过,可以将isFinished设为yes
    if (self.isExecuting) {
        self.finished = YES;
        self.executing = NO;
    }
}

-(void)setFinished:(BOOL)finished {
    [self willChangeValueForKey:@"isFinished"];
    _finished = finished;
    [self didChangeValueForKey:@"isFinished"];
}

-(void)setExecuting:(BOOL)executing {
    [self willChangeValueForKey:@"isExecuting"];
    _executing = executing;
    [self didChangeValueForKey:@"isExecuting"];
}

- (BOOL)isAsynchronous {
    return YES;
}

手动维护的好处 在子线程操作的时候 防止 operation isFinish被设为YES 当要操作的时候 已经被提前释放掉

相关文章

网友评论

      本文标题:NSOperation

      本文链接:https://www.haomeiwen.com/subject/hzeytctx.html