wallace
wallace

Reputation: 454

How to lazily set BOOL property in Objective-C

I need a BOOL property on a data structure, representing the state of some object in a database, and I want to set that property lazily -- that is, I don't want to ping the db until I need to, and only set the property at that point (i.e., the first time I get it).

For something like an NSString, I'd make a getter like

- (NSString *)myString {
    if (!_myString) {

        // ask db for value
        _myString = [value returned from db]

    }
    return _myString;
}

But it seems BOOLs default to NO in Objective-C -- which means I would never know whether the value is in fact NO, or I just haven't ever gotten it yet. I have poked around, but I can't seem to figure out how to create the kind of getter I have in mind for such a property. Any suggestions? Or am I missing something quite obvious? Thanks in advance.

Upvotes: 3

Views: 883

Answers (2)

Caleb
Caleb

Reputation: 124997

IF you only need to do this initialization once, and not once per instance of the class, dispatch_once() can be a nice tool:

- (BOOL)myBool {
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        // initialize _myBool here
    });
    return _myBool;
}

From a practical standpoint, it's really not so different from other solutions: you need to remember whether you've already initialized the state somehow, and whether you do it by storing your state in a pointer that can be nil, or in an int that can have some "uninitialized" value, or in a static once variable doesn't make much difference codifies.

What I like about this method, though, is that it clearly conveys your intention: you want this thing to happen the only first time myBool is called. It also lets you store your myBool property as a BOOL rather than as some other type that you have to translate to a BOOL, which again more clearly communicates your intention.

Upvotes: 1

Bannings
Bannings

Reputation: 10479

You can use an NSNumber in the inside of object:

// .h
@interface Object : NSObject

@property (nonatomic, assign) BOOL myBool;

@end

//.m
@interface Object ()

@property (nonatomic, strong) NSNumber *myBoolFromDB;

@end

@implementation Object

- (BOOL) myBool {
    if (_myBoolFromDB == nil) {
        ...
    }
    return [_myBoolFromDB boolValue];
}

@end

Upvotes: 6

Related Questions