Reputation: 26223
If I create a custom initWith for an object do I essentially include the code I would add should I want to override init?
-(id) init {
self = [super init];
if (self) {
NSLog(@"_init: %@", self);
}
return(self);
}
e.g.
-(id) initWithX:(int) inPosX andY:(int) inPosY {
self = [super init];
if(self) {
NSLog(@"_init: %@", self);
posX = inPosX;
posY = inPosY;
}
return(self);
}
gary
Upvotes: 51
Views: 52666
Reputation: 341
I'd suggest creating one main initializer that handles most of the work. You can then create any number of other initializers that all call this main one. The advantage of this is if you want to change the initialization process, you'll only have to change one spot. It might look like this:
-(id) initWithX:(float)x {
if (self = [super init]) {
/* do most of initialization */
self.xVal = x;
}
return self;
}
-(id) init {
return [self initWithX:0.0f];
}
In this example initWithX: is our main initializer. The other initializer (init) simply calls initWithX: with a default value (in this case 0).
Upvotes: 10
Reputation: 51931
For modern Objective-C ...
UDFile.h
#import <Foundation/Foundation.h>
@interface UDFile : NSObject
@property (nonatomic, strong) NSString *name;
- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
@end
UDFile.m
#import "UDFile.h"
@implementation UDFile
- (instancetype)initWithName:(NSString *)name {
self = [super init];
if (self) {
_name = [name copy];
}
return self;
}
- (instancetype)init {
return [self initWithPathname:@""];
}
Upvotes: 5
Reputation: 79790
You can create one designated initializer that accepts all parameters that you want to make available in initialization.
Then you call from your other -(id)init
your designated initializer with proper parameters.
Only the designated initializer will initialize super class [super init]
.
Example:
- (id)init
{
return [self initWithX:defaultX andY:defaultY];
}
- (id)initWithPosition:(NSPoint)position
{
return [self initWithX:position.x andY:position.y];
}
- (id)initWithX:(int)inPosX andY:(int)inPosY
{
self = [super init];
if(self) {
NSLog(@"_init: %@", self);
posX = inPosX;
posY = inPosY;
}
return self;
}
The designated initializer is -(id)initWithX:andY:
and you call it from other initializers.
In case you want to extend this class you call your designated initializer from subclass.
Upvotes: 97
Reputation: 95335
Sometimes, you want to reuse some initialisation code and modify the behaviour only slightly for specific initialisers. In this case, I do the following:
- (id) init
{
self = [super init];
if (!self) return nil;
// These values are always initialised this way
ivar1 = 10;
ivar2 = @"HellO";
ivar3 = [[NSMutableArray alloc] initWithCapacity:10];
ivar4 = 22;
return self;
}
- (id) initWithIvar4:(int) aValue
{
// call -init on self, which will call -init on super for us, and set
// up ivar1, ivar2, ivar3, and ivar4.
self = [self init];
if (!self) return nil;
// Change ivar4 from the default 22 to whatever aValue is.
ivar4 = aValue;
return self;
}
Upvotes: 2
Reputation: 6120
Yes, that's exactly how I do it. One slight change will cut out a line of code:
if (self = [super init]) {
As opposed to:
self = [super init];
if(self) {
Upvotes: 6