jhabbott
jhabbott

Reputation: 19311

Automatic lazy creation of automatic properties in objective-c

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

Answers (2)

nielsbot
nielsbot

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

rob mayoff
rob mayoff

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

Related Questions