Sometimes you put a delayed operation being a flag which you can clear to cancel. It might look like this:
- (void)primeOperation {
self.flag = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, someTimeInSecs * NSEC_PER_SEC), dispatch_get_main_queue(), ^() {
if (self.flag) {
self.flag = NO;
//do something
}
});
}
But the problem with this approach is after if you clear the flag and set up the operation again soon enough, you will end up with running that operation twice:
- (void)doSomething {
[self primeOperation];
self.flag = NO;
[self primeOperation];
}
One of the ways to work around this is to create an NSOperation
subclass.
Alternatively, you can create a lightweight class that wraps around a BOOL
:
@interface BoolWrapper: NSObject
@property(nonatomic) BOOL state;
+ (instancetype)wrapperWithBool:(BOOL)state;
@end
@implementation BoolWrapper
+ (instancetype)wrapperWithBool:(BOOL)state {
BoolWrapper* result = [self new];
result.state = state;
return result;
}
@end
You can change your code so that flag
is now an instance of BoolWrapper
:
- (void)primeOperation {
self.flag = [BoolWrapper wrapperWithBool:YES];
BoolWrapper* previousFlag = self.flag;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, someTimeInSecs * NSEC_PER_SEC), dispatch_get_main_queue(), ^() {
if (self.flag == previousFlag && self.flag.state) {
self.flag = [BoolWrapper wrapperWithBool:NO];
//do something
}
});
}
This will now work since the identity check self.flag == previousFlag
takes care that we are referring to the same "operation".
Your feedback is valuable: Do you want more nuggets like this? Yes or No
.
.