A factory method can be any class or instance method that returns a newly created and initialized object.
A "class factory method" in the more stringent context of Objective-C is any class method of the class Class whose name begins with the class .., with its prefix separated and the first letter in lower case. Example for the Foo class:
+(Foo*) fooWithParam:(NSDictionary*)param;
For convenience, one of the reasons for using factory class methods is used. If you have a Foo class, it can be created as follows:
Foo* foo = [[Foo alloc] initWithParam:param];
Now you can use the convenient factory class:
Foo* foo = [Foo fooWithParam:param];
However, there are other reasons why the factory class method is useful:
Suppose, for example, that the initWithParam: may fail. Then there is a lot of confusion about how this should be handled: should an exception be thrown from init? Or do you need to return nil ? Controversial debate about the right approach in society. Both approaches have subtle issues, including memory leaks that cannot be avoided.
Thus, the most reasonable approach in this case would be to use a factory class method with an error parameter. Here you get the Foo object as follows:
NSError* error; Foo* foo = [Foo fooWithParam:param error:&error];
Now this is the rule: If foo is zero, an error has occurred, and you can get detailed information about the error with an output parameter error:
if (foo) { ... } else { NSLog(@"Error: %@", error); }
Typically, an implementation will look like this:
+ (Foo*) fooWithParam:(NSDictionary*)param error:(NSError**error) { if ([param count] < 1) { // invalid parameters if (error) { NSError* error = [NSError errorWithDomain:@"Foo" code:-1000 userInfo: ...]; } return nil; } return [[self alloc] initWithParam:param]; // won't fail }
Another reason is to implement class clusters. This basically means that the factory method of the class returns a subclass of the class. An example is the NSStream class.
The NSInputStream class has a factory class method:
+ (id)inputStreamWithFileAtPath:(NSString *)path;
Returns the specialized class NSInputStream .
There is an important detail in the ARC pre-hall:
The objects returned from the factory class are "autoreleased". In other words, the client receiving the object does not own it - and therefore does not need to release it.
Currently, with ARC, these details have become blurry: in any case, you do not need to release these objects manually. How and when an object is actually freed is also subject to compiler optimization.