Is the lazy attribute in Swift equivalent to overriding the getter with a lazy loading pattern in Objective C?
3 Answers
From the docs:
A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy attribute before its declaration.
So, mostly, yes.
You must always declare a lazy property as a variable (with the var keyword), because its initial value may not be retrieved until after instance initialization completes. Constant properties must always have a value before initialization completes, and therefore cannot be declared as lazy.”
Remember that on Swift you have the option to declare custom getters and setters for your properties:
var name : String?{
get{
return "Oscar"
}
set(newValue){
}
}
3 Comments
Referring to this:
lazy var x = SomeFunction()
The closest equivalent in Objective-C would be something like:
@property BOOL xHasBeenSet;
@property id x;
- (id)x
{
if (!self.xHasBeenSet) {
self.x = SomeFunction();
}
return x;
}
- (void)setX:(id)x
{
_x = x;
self.xHasBeenSet = YES;
}
Here you would only see SomeFunction called the first time you read x, but only if you don't set x first. It's important to note that there is only one code path where the right side gets called and it never resets back to xHasBeenSet = NO.
5 Comments
- (id)x { if(!_x) _x = someFunction()SomeFunction() could return 0 or nil, the RHS would still only be called once.- (id)x { dispatch_once(^{ if(!_x) _x = boa; }); return _x; } [I left out the token because I always get the syntax wrong anyways :D]self.x = ... was out of laziness since setting flipped two variables.x = 0 before calling. It's tricky business. But yes, there's probably also a lock involved for thread safety.