Search code examples
objective-cobjectinitializationimplementationalloc

Programmatic Object Creation in Objective-C


Below there are two methods to programmatically alloc and init objects of various classes and 'types'.

- (id)buildObjectOfClass:(NSString *)classString andType:(NSString *)typeString
    {
    id buildObject;
    Class className             = NSClassFromString(classString);
    SEL initWithTypeSelector    = NSSelectorFromString(@"initWithType:");

    if ([className instancesRespondToSelector:initWithTypeSelector] == YES) {
        buildObject = [[className alloc] performSelector:initWithTypeSelector 
                                              withObject: typeString];
    }
    return buildObject;
}

This method implementation was originally written more tersely as simply:
{ return [[className alloc] initWithType:typeString]; }

My questions are: 1) is the verbose version necessary? and 2) if so, was it programmed as best as it could be? Are there shortcuts or best practices I am neglecting?


Solution

  • The difference between the verbose and terse versions of this method are that the verbose version validates that the class instances can actually respond to -initWithType: which is not a standard NSObject init function.

    It is unnecessary to use the verbose version if any of the following were true:

    • You are only using -init and not -initWithType:
    • You are certain that every class you instantiate will be able to handle -initWithType:
    • You don't mind the application unexpectedly quitting with an unknown method exception if the class you instantiate does not respond to -initWithType:

    This version (although you should set buildObject to nil to handle the error case explicitly) returns nil if the class isn't found or if it doesn't respond to -initWithType:. The terse version returns nil if the class isn't found and throws an exception if the class instances don't respond to -initWithType:.