星空网 > 软件开发 > 操作系统

创建一个支持异步操作的operation

NSOperationQueue时iOS中常用的任务调度机制。在创建一个复杂任务的时候,我们通常都需要编写?NSOperation的子类。在大部分情况下,重写main方法就可以满足要求。main方法执行完毕后,系统就会认为这个operation完成了。

 

有时候情况并没有这么简单。我们需要在operation中调用异步的API,这个API会通过一个block或者代理通知我们结果。这时只靠覆盖main方法就显得力不从心了。因为异步API尚未执行完毕,operation就提前结束了。

 

怎么解决这个问题呢?我想到AFNetworking中有同样的案例,于是参考了其中的实现,设计了一个基于异步任务的operation。

 

我们需要覆盖start方法。这个方法的作用有点类似于main方法,在这里实现任务的代码逻辑。系统怎么知道我们的任务开始执行,或者完成了呢?系统会通过KVO的形式,监听operation的一些属性。我们可以重新实现这些属性,来通知系统任务执行的状态。重要的属性有:

@property (readonly, getter=isReady) BOOL ready;@property (readonly, getter=isExecuting) BOOL executing;@property (readonly, getter=isFinished) BOOL finished;

 

它们都是只读属性。我们可以简单的重写它们,返回我们想要的值。但是如何通知系统它们的值已经变化了呢?如果你了解KVO,那么你就应该知道NSObject的这一对方法能够帮助我们,可以利用它们手动通知系统某个属性发生了变化。

- (void)willChangeValueForKey:(NSString *)key;- (void)didChangeValueForKey:(NSString *)key;

 

下面就是完整的代码。这里只用了一个NSTimer模拟一个异步的任务。在state变化时,我们需要通知KVO系统operation的状态发生了变化。这一步很重要,我刚开始忽略了手动通知KVO,导致任务永远无法完成(即使start中的任务全部执行完毕)。

typedef NS_ENUM(NSInteger, MyOperationState) {  MyOperationStateReady,  MyOperationStateExecuting,  MyOperationStateFinished};@interface MyOperation : NSOperation@property (nonatomic, strong) NSTimer *exeTimer;@property (nonatomic, assign) MyOperationState state;@property (nonatomic, strong) NSLock *lock;@end@implementation MyOperation- (instancetype)init{  self = [super init];  if (self) {    self.lock = [NSLock new];    [self willChangeValueForKey:@"isReady"];    self.state = MyOperationStateReady;    [self willChangeValueForKey:@"isReady"];  }  return self;}- (void)start{  [self.lock lock];  if (!self.finished && self.state == MyOperationStateReady) {    [self willChangeValueForKey:@"isExecuting"];    self.state = MyOperationStateExecuting;    [self didChangeValueForKey:@"isExecuting"];    self.exeTimer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(finish) userInfo:nil repeats:NO];    [[NSRunLoop mainRunLoop] addTimer:self.exeTimer forMode:NSRunLoopCommonModes];  }  [self.lock unlock];}- (void)cancel{  [self.lock lock];  if (!self.isFinished && !self.cancelled) {    [super cancel];    [self.exeTimer invalidate];  }  [self.lock unlock];}- (BOOL)isReady{  return self.state == MyOperationStateReady;}- (BOOL)isExecuting{  return self.state == MyOperationStateExecuting;}- (BOOL)isFinished{  return self.state == MyOperationStateFinished;}- (BOOL)isAsynchronous{  return YES;}- (BOOL)isConcurrent{  return YES;}- (void)finish{  [self.lock lock];  [self willChangeValueForKey:@"isFinished"];  self.state = MyOperationStateFinished;  [self didChangeValueForKey:@"isFinished"];  [self.lock unlock];}@end

 




原标题:创建一个支持异步操作的operation

关键词:异步

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

泰国fba专线:https://www.goluckyvip.com/tag/42296.html
泰国shopee:https://www.goluckyvip.com/tag/42297.html
泰国国王日:https://www.goluckyvip.com/tag/42298.html
泰国海外仓:https://www.goluckyvip.com/tag/42299.html
中方态度坚定:https://www.goluckyvip.com/tag/423.html
泰国海外仓分销:https://www.goluckyvip.com/tag/42300.html
黄仁勋问答全文:关于中国市场、全球供应链、奥特曼和Groq :https://www.kjdsnews.com/a/1836443.html
200万上下文!月之暗面Kimi又长长长了:一次处理500个文件 还能读懂甄嬛传 :https://www.kjdsnews.com/a/1836444.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流