Reputation: 19311
I have a property
@property (strong, nonatomic, readonly) NSMutableArray* myArray;
and I want to lazily create the array in the getter
- (NSMutableArray*)myArray
{
if(_myArray == nil)
{
_myArray = [NSMutableArray arrayWithCapacity:4];
}
return _myArray;
}
but this breaks the automatic synthesis of the iVar (`_myArray), negating some of the benefits of automatic synthesis meaning you have to do things the old way.
This is a very common pattern and it would be nice to have automatic synthesis of a lazy-create version of the getter. I guess this would take an extension to the Objective-C language and compilers, for example with an additional property attribute like this:
@property (strong, nonatomic, readonly, lazycreate) NSMutableArray* myArray;
Any class that implements a pre-defined class method (in a similar way to object subscripting described here) such as + (ClassType*)defaultConstructor
could support the lazycreate
property attribute and automatic synthesis could then synthesize the getter in my example like this:
- (NSMutableArray*)myArray
{
if(_myArray == nil)
{
_myArray = [NSMutableArray defaultConstructor];
}
return _myArray;
}
Am I right that this would require a language extension, or is there a clever way to achieve it now?
Are there any problems or pitfalls with this idea and what are they?
How do I propose this idea into the Objective-C language?
Upvotes: 0
Views: 322
Reputation: 16031
You should check out the metaprogramming methods available on NSObject, such as -implementationForMethod
. This allows you to provide an implementation of a missing method at runtime.
You can use this to provide a getter/setter dynamically for any declared properties.
You might then read from a dictionary of default values..
You could also try overriding -valueForUndefinedKey:
This might help: https://gist.github.com/2370784
Upvotes: 0
Reputation: 385920
Adding a new property attribute like lazycreate
requires modifying the compiler. You can ask Apple to add it by opening a new problem at http://bugreport.apple.com. The product is “Developer Tools” and the classification is “Feature (New)”.
You could define a macro like this:
#define synthesizeLazy(Type, Property) \
synthesize Property = _##Property; \
- (Type *)property { \
if (_##Property == nil) { _##Property = [[Type alloc] init]; } \
return _##Property; \
}
and then use it to synthesize your lazy properties like this:
@synthesizeLazy(NSMutableArray, myArray);
There's no good way to fake it with completely automatic synthesis.
Upvotes: 1