Reputation: 2946
I've seen a way of initialising a view controller that intrigued me. Could be my lack of experience, but I find it very useful, however, I'm trying to see if there are any reasons for which one should avoid it so I know if I should adopt it as well.
UIViewController* imageC = [UIViewController imageViewController];
Where imageViewController
is a static method in a category:
+(UIViewController*) imageViewController
{
return [[UIViewController alloc] initWithNibName:@"ImageViewController" bundle:nil];
}
Is this good, reliable design? I think so, but not sure. Being a static method means it lacks context, but not sure that's a problem in this case. What are the problems you can run in on long term if you use this approach?(If any)
Upvotes: 1
Views: 602
Reputation: 69027
UIViewController* imageC = [UIViewController imageViewController];
This is known as a convenience constructor or factory method and is perfectly legal and useful. BTW, it is a class method, not a static method.
A convenience constructor has two main traits:
it offers a more convenient syntax to instantiate a class over the standard alloc/init;
it returns an autorelease
object that will be deallocated at the end of the current scope or at the end of the current autorelease pool.
By now you have probably noticed in the class documentation that most Cocoa classes have a set of class methods that are named in the format +className.... These special class methods are called "convenience constructors," and are used to create temporary objects. What I mean by temporary is that objects returned by a convenience constructor are assumed to be autoreleased [...].
(source)
EDIT: more details about the mechanism of convenience constructors (and in general about return references) can be found in the Objective C ARC Reference, sec. 3.2.2.
Upvotes: 2
Reputation: 81868
There are a couple of issues with your code. First, there are no static methods in Objective C. There are class methods, and they, same as instance methods, do dynamic dispatch. They just use the class object for this.
And that leads us to the second issue: Your code always allocates an instance of UIViewController
, even when called on a subclass. That's not expected behavior for Objective-C. [NSMutableArray array]
returns a mutable array, even though array
is a convenience constructor defined in NSArray
.
The third issue is minor: It would be beneficial for users of subclasses if you would declare your method to return instancetype
. That way your saying the method returns an instance of the receiver class and the compiler can do its static type checking. The concept is called related return type
and was only recently introduced with clang.
Here's a better version:
+ (instancetype)imageViewController
{
return [[self alloc] initWithNibName:@"ImageViewController" bundle:nil];
}
Upvotes: 2