NSOperation 与 NSOperationQueue是什么?
@interface NSOperation : NSObject
@interface NSOperationQueue : NSObject
NSOperation
、 NSOperationQueue
是系统给我提供的一套多线程API 它们是基于GCD 更高层次的封装 完全面向对象。 相对于C语言的API 使用更加方便 可读性也更高。
NSOperation 与 GCD比较有哪些优势?
- 基于GCD的封装 可读性强 使用起来方便
2.可以添加依赖 方便控制执行顺序
3.可以设定执行的优先级
4.可以更方便的取消一个操作的执行
5.可以使用KVO观察任务的执行状态
与GCD相同 它也具备 任务 队列的概念
NSOperation
苹果框架使用了大量的抽象思想 NSOperation
也不例外 我们不能直接使用 NSOperation
需要用系统提供的的子类 NSBlockOperation
、NSInvocationOperation
或 继承来创建 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
放到那个线程 它会一直阻塞住那个线程 直到 operation
的 finished
变为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 当要操作的时候 已经被提前释放掉
网友评论