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?
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:
-init
and not -initWithType:
-initWithType:
-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:
.