Commit 92a77a84 by Dima Bart

Update thread-safe implementation of 'state' to use atomic property.

- remove the need for using NSLock to update `state`
- remove the need for using NSLock to update `currentTask`
- add KVO dependencies from `state` -> `isFinished` & `isExecuting`
parent 019f777b
......@@ -28,8 +28,6 @@
@interface BUYOperation : NSOperation
- (void)locked:(dispatch_block_t)lockedBlock;
- (void)startExecution;
- (void)finishExecution;
- (void)cancelExecution;
......
......@@ -33,22 +33,22 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) {
@interface BUYOperation ()
@property (nonatomic, assign) BUYOperationState state;
@property (nonatomic, strong) NSLock *lock;
@property (atomic, assign) BUYOperationState state;
@end
@implementation BUYOperation
#pragma mark - Init -
#pragma mark - KVO -
- (instancetype)init
+ (NSSet *)keyPathsForValuesAffectingIsExecuting
{
self = [super init];
if (self) {
_lock = [NSLock new];
}
return self;
return [NSSet setWithObject:@"state"];
}
+ (NSSet *)keyPathsForValuesAffectingIsFinished
{
return [NSSet setWithObject:@"state"];
}
#pragma mark - Concurrent -
......@@ -68,41 +68,6 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) {
return self.state == BUYOperationStateFinished;
}
#pragma mark - Setters -
- (void)locked:(dispatch_block_t)lockedBlock
{
[self.lock lock];
lockedBlock();
[self.lock unlock];
}
- (void)setState:(BUYOperationState)state
{
[self.lock lock];
NSString *oldPath = BUYOperationStateKeyPath(self.state);
NSString *newPath = BUYOperationStateKeyPath(state);
/* ----------------------------------
* We avoid changing state if the new
* state is the same or the operation
* has been cancelled.
*/
if ([oldPath isEqualToString:newPath] || self.isCancelled) {
[self.lock unlock];
return;
}
[self willChangeValueForKey:newPath];
[self willChangeValueForKey:oldPath];
_state = state;
[self didChangeValueForKey:oldPath];
[self didChangeValueForKey:newPath];
[self.lock unlock];
}
#pragma mark - Start -
- (void)start
{
......@@ -128,18 +93,7 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) {
- (void)cancelExecution
{
[self finishExecution];
}
#pragma mark - State -
static inline NSString * BUYOperationStateKeyPath(BUYOperationState state)
{
switch (state) {
case BUYOperationStateFinished: return @"isFinished";
case BUYOperationStateExecuting: return @"isExecuting";
}
return @"";
}
@end
......@@ -36,6 +36,7 @@ typedef BOOL (^BUYRequestOperationPollingHandler)(NSDictionary * _Nullable json,
@property (strong, nonatomic, readonly, nonnull) NSURLSession *session;
@property (strong, nonatomic, readonly, nonnull) NSURLRequest *originalRequest;
@property (strong, nonatomic, readonly, nonnull) BUYRequestOperationCompletion completion;
@property (strong, nonatomic, nullable) BUYRequestOperationPollingHandler pollingHandler;
......
......@@ -57,8 +57,7 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *
@interface BUYRequestOperation ()
@property (strong, nonatomic) BUYRequestOperationCompletion completion;
@property (strong, nonatomic) NSURLSessionDataTask *runningTask;
@property (strong, atomic) NSURLSessionDataTask *runningTask;
@end
......@@ -112,21 +111,15 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *
[self finishWithError:error response:response];
}
}];
[self locked:^{
self.runningTask = task;
}];
self.runningTask = task;
[task resume];
}
- (void)cancelExecution
{
[super cancelExecution];
__block NSURLSessionDataTask *task = nil;
[self locked:^{
task = self.runningTask;
}];
[task cancel];
[self.runningTask cancel];
}
#pragma mark - Requests -
......@@ -151,9 +144,7 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *
*/
if (self.pollingHandler && self.pollingHandler(json, response, error)) {
NSURLSessionDataTask *task = [self requestUsingPollingIfNeeded:request completion:completion];
[self locked:^{
self.runningTask = task;
}];
self.runningTask = task;
[task resume];
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment