Question

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?

Was it helpful?

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:.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top