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 @@ ...@@ -28,8 +28,6 @@
@interface BUYOperation : NSOperation @interface BUYOperation : NSOperation
- (void)locked:(dispatch_block_t)lockedBlock;
- (void)startExecution; - (void)startExecution;
- (void)finishExecution; - (void)finishExecution;
- (void)cancelExecution; - (void)cancelExecution;
......
...@@ -33,22 +33,22 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) { ...@@ -33,22 +33,22 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) {
@interface BUYOperation () @interface BUYOperation ()
@property (nonatomic, assign) BUYOperationState state; @property (atomic, assign) BUYOperationState state;
@property (nonatomic, strong) NSLock *lock;
@end @end
@implementation BUYOperation @implementation BUYOperation
#pragma mark - Init - #pragma mark - KVO -
- (instancetype)init + (NSSet *)keyPathsForValuesAffectingIsExecuting
{ {
self = [super init]; return [NSSet setWithObject:@"state"];
if (self) { }
_lock = [NSLock new];
} + (NSSet *)keyPathsForValuesAffectingIsFinished
return self; {
return [NSSet setWithObject:@"state"];
} }
#pragma mark - Concurrent - #pragma mark - Concurrent -
...@@ -68,41 +68,6 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) { ...@@ -68,41 +68,6 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) {
return self.state == BUYOperationStateFinished; 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 - #pragma mark - Start -
- (void)start - (void)start
{ {
...@@ -128,18 +93,7 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) { ...@@ -128,18 +93,7 @@ typedef NS_ENUM(NSUInteger, BUYOperationState) {
- (void)cancelExecution - (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 @end
...@@ -36,6 +36,7 @@ typedef BOOL (^BUYRequestOperationPollingHandler)(NSDictionary * _Nullable json, ...@@ -36,6 +36,7 @@ typedef BOOL (^BUYRequestOperationPollingHandler)(NSDictionary * _Nullable json,
@property (strong, nonatomic, readonly, nonnull) NSURLSession *session; @property (strong, nonatomic, readonly, nonnull) NSURLSession *session;
@property (strong, nonatomic, readonly, nonnull) NSURLRequest *originalRequest; @property (strong, nonatomic, readonly, nonnull) NSURLRequest *originalRequest;
@property (strong, nonatomic, readonly, nonnull) BUYRequestOperationCompletion completion;
@property (strong, nonatomic, nullable) BUYRequestOperationPollingHandler pollingHandler; @property (strong, nonatomic, nullable) BUYRequestOperationPollingHandler pollingHandler;
......
...@@ -57,8 +57,7 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse * ...@@ -57,8 +57,7 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *
@interface BUYRequestOperation () @interface BUYRequestOperation ()
@property (strong, nonatomic) BUYRequestOperationCompletion completion; @property (strong, atomic) NSURLSessionDataTask *runningTask;
@property (strong, nonatomic) NSURLSessionDataTask *runningTask;
@end @end
...@@ -112,21 +111,15 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse * ...@@ -112,21 +111,15 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *
[self finishWithError:error response:response]; [self finishWithError:error response:response];
} }
}]; }];
[self locked:^{
self.runningTask = task; self.runningTask = task;
}];
[task resume]; [task resume];
} }
- (void)cancelExecution - (void)cancelExecution
{ {
[super cancelExecution]; [super cancelExecution];
[self.runningTask cancel];
__block NSURLSessionDataTask *task = nil;
[self locked:^{
task = self.runningTask;
}];
[task cancel];
} }
#pragma mark - Requests - #pragma mark - Requests -
...@@ -151,9 +144,7 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse * ...@@ -151,9 +144,7 @@ typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *
*/ */
if (self.pollingHandler && self.pollingHandler(json, response, error)) { if (self.pollingHandler && self.pollingHandler(json, response, error)) {
NSURLSessionDataTask *task = [self requestUsingPollingIfNeeded:request completion:completion]; NSURLSessionDataTask *task = [self requestUsingPollingIfNeeded:request completion:completion];
[self locked:^{ self.runningTask = task;
self.runningTask = task;
}];
[task resume]; [task resume];
} else { } 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