Create an operation that supports asynchronous operations and an Asynchronous operation

Source: Internet
Author: User

Create an operation that supports asynchronous operations and an Asynchronous operation

NSOperationQueue is a common task scheduling mechanism in iOS. When creating a complex task, do we usually need to write? NSOperation subclass. In most cases, rewrite the main method to meet the requirements. After the main method is executed, the system will think that the operation is complete.

 

Sometimes the situation is not that simple. We need to call the asynchronous API in operation. This API will notify us of the result through a block or proxy. In this case, only the main method can be overwritten. Because the asynchronous API has not been executed, operation is completed ahead of schedule.

 

How can this problem be solved? I think AFNetworking has the same case, so I designed an asynchronous Task-based operation based on the implementation.

 

We need to overwrite the start method. The function of this method is somewhat similar to the main method, where the code logic of the task is implemented. How does the system know that our task is being executed or completed? The system listens to some operation attributes in the form of KVO. We can re-implement these attributes to notify the System of the task execution status. Important attributes include:

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

 

They are all read-only attributes. We can simply rewrite them and return the values we want. But how can we notify the system that their values have changed? If you know KVO, you should know that the NSObject method can help us, and you can use them to manually notify the system that a certain attribute has changed.

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

 

The following is the complete code. Here we only use an NSTimer to simulate an asynchronous task. When the state changes, we need to notify the KVO system that the operation status has changed. This step is very important. I ignored manual notifications to KVO at the beginning, causing tasks to never be completed (even if all the tasks in start are completed ).

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

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.