Reputation: 15589
I have class A which inherits class B. And want to achieve something like below. But the init methods get recursive call due to dynamic typecasting. Is there any way to achieve such? Any suggestion? (without changing 'init's name in subclass?
@interface A : NSObject
@property NSData * data;
@end
@implementation A
- (id) init {
self = [super init];
/* want to do some default initialization here
for this class and all of its subclasses. */
// ... ...
return self;
}
/* This [self init] get recursed.
But how can I force this class and all of its subclass to call [self init] above,
not to call the subclass's init method. */
- (id) initWithData:(NSData *)d {
self = [self init];
self.data = d;
return self;
}
@end
@interface B : A
@end
#import "B.h"
@implementation B
- (id) init {
self = [super initWithData:nil];
// some subclass specific init code here ...
return
}
@end
Using B,
- (void) testInit{
B * b = [[B alloc] init];
}
Upvotes: 1
Views: 1458
Reputation: 15589
Here is an example of designated initilizer pattern mentioned above,
#import ”Person.h”
@implementation Person
-(id) initWithAge:(int)theAge AndHeight:(int)theHeight AndName:(NSString *)theName {
if (self = [super init]){
_age = theAge;
_height = thefleight;
_name = theName;
}
return self;
}
-(id) initwithAge:(int)theAge AndHeight:(int)theHeight {
return [self initWithAge:theAge AndHeight:theHeight AndName:nil];
}
-(id) initwithAge:(int)theAge {
return [self initWithAge:theAge AndHeight:0];
}
- (id)init {
return [self initwithAge:0];
}
@end
Upvotes: 1
Reputation: 8012
Look up the "designated initializer" pattern. It describes how to arrange initializer methods and convenience constructors (a.k.a. factory methods) in a class hierarchy.
Upvotes: 1
Reputation: 1299
You're calling [self init]
in your implementation which is causing the recursion issue..
Implement this way :
- (id) init {
self = [super init];
//Basic empty init...
return self;
}
- (id) initWithData:(NSData *)d
{
self = [super init]; //<---- check this line.
if(self)
{
self.data = d;
}
return self;
}
//If you are looking to write some init code only 1 time the the following can work.....
-(void)oneTimeWrittenInitCode:(id)mySelf
{
//your init code which you wish to write one time goes here...
}
- (id) init {
self = [super init];
if(self)
{
[self oneTimeWrittenInitCode:self];
}
return self;
}
- (id) initWithData:(NSData *)d
{
self = [super init];
if(self)
{
[self oneTimeWrittenInitCode:self];
self.data = d;
}
return self;
}
Upvotes: 6
Reputation: 25917
It should be:
- (instancetype) initWithData:(NSData *)d
{
if(self = [super init])
{
_data = d;
}
return self;
}
Upvotes: 0