I read here (Is there a convention for naming initializer method in objective-c?) that "according to Apple, initializer methods should always begin with the word 'init'".
But, what is an initializer?
I know what is the "designated initializer". You could define it recursively: it is the only method calling the designated initializer of super
; plus: the designated initializer of NSObject is init
.
But, what is an initializer?
I am asking this question because I hesitate between two names for an instance method of the class IceCream
:
- (id)initIceCreamWithFlavour:
- (id)iceCreamWithFlavour:
("called on alloc
")
I feel that relatively to the naming conventions of ARC, both names are OK. (This is my main concern here. Comments are welcome.) Now that I ask the question, the
solution (id)iceCreamWithFlavour:
seems better.
But the question still holds: what is an initializer?
I would say: an initializer is a method you "call on alloc
".
I would use - (id)initWithFlavour:
.
So you would have:
IceCream *iceCream = [[IceCream alloc] initWithFlavour:Chocolate];
which tell you everything you need to know at a glance about the class and the initialisation parameter purpose. Restating ice cream in the method name is superfluous.
As for what the init
method is, it's just the initialiser for the class. It's purpose is to create a configured new instance. To setup the default values (with, as in this case, some overrides or specific settings).
From your other method naming attempt, you could have:
+ (id)iceCreamWithFlavour:
Note the plus instead of minus, so this is a class method. This would be a suitable name for a convenience method which calls alloc] initWithFlavour:
and returns the new instance.
Incidentally, if we add more parameters, don't restate with
:
IceCream *iceCream = [[IceCream alloc] initWithFlavour:Chocolate sprinkles:YES];
Objective-C uses a 2 step creation process for objects.
The first step is memory allocation, and the second step is initialisation (which sets the initial state of an object):
MYIceCream* iceCream = [[MYIceCream alloc] initWithFlavor:@"Cherry"];
You can have multiple init
methods for your classes, but you should have only one of them that sets the complete state for a new object. This is the designated initialiser (which usually takes the most parameters).
The MYIceCream
class could have the following designated initialiser:
- (id)initWithFlavor:(NSString*)flavorName topping:(NSString*)toppingName
{
self = [super init];
if (self)
{
_flavorName = flavorName;
_toppingName = toppingName;
}
return self;
}
All other initialisers would just call the above method and provide defaults (or nil
) for some parameters:
- (id)initWithFlavor:(NSString*)flavorName
{
return [self initWithFlavor:flavorName topping:kMYToppingChoclate];
}
You can also define methods, that combine allocation and initialisation. Those are called factory methods. They are defined as class methods (denoted with a +
sign) and don't have an init
prefix:
+ (id)iceCreamWithFlavor:(NSString*)flavorName;
The factory method would just call alloc
and init
in it's implementation:
+ (id)iceCreamWithFlavor:(NSString*)flavorName
{
return [[MYIceCream alloc] initWithName:flavorName];
}
Apple has a good intro to initialisers in the Cocoa Core Competencies guide and another good read in the Objective-C Programming Guide.
I would say: an initializer is a method you "call on alloc"
Thats partly true.
There are 3 types of "direct" initializers as far as i know :
[init] initializer (following [X alloc] call)
Initializers starting with "init" always follow an alloc call. I haven't seen any UIKit or Foundation Class being initialized like : [[NSArray alloc] arrayWithObject:] <- Does not exist like that.
Class - initializers
Class initializer create an object from a class scope without having called alloc before.
The implementation of this method, however, would sure call an [[alloc] init]
to create an object.
Example : [NSMutableArray arrayWithCapacity:]
Class initializers always start with the corresponding class name.
In your case :
[IceCream iceCreamWithFlavor:]
Initializers creating from existing object.
These are creating an object from an existing one. They 'copy' the existing object and alter some properties.
Example:
UIColor *red = [UIColor redColor];
UIColor *thinRedColor = [red colorWithAlphaComponent:0.5];
They also start with their corresponding class name like the Class - initializers
If you look through the UIKit and Foundation classes, you will find that these patterns are used in every Class ( & Class - Cluster).
So to answer your question:
The "UIKit / Foundation" - way of naming your initializers would be :
When called after alloc
:
- (instancetype)initWithFlavour:
When called on an existing object :
- (instancetype)iceCreamWithFlavourAlteredByValue:
When called on your Class-Object :
+ (instancetype)iceCreamWithFlavour:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With