Clicky

iOS Dev Nugget 243 Wrapping BOOL in a Class

.

Need to run a code review on your codebase? Hire me

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

.

.

Like this and want such iOS dev nuggets to be emailed to you, weekly?

Sign Me Up! or follow @iosdevnuggets on Twitter

.

View archives of past issues