There are three class Question
,Choice
and Blank
,and Question
is the super class of Choice
and Blank
.
Then, I write some methods as follows:
- (instancetype)initWithQuestionType:(NSString *)questionType
{
NSLog(@"**class:%@",[self class]);
if([self isMemberOfClass:[Question class]])
{
self = nil;
if([questionType isEqualToString:@"choice"])
{
NSLog(@"--class:%@",[self class]);
self = [[Choice alloc] initWithQuestionType:questionType];
NSLog(@"++class:%@",[self class]);
}
else
{
self = [[Blank alloc] initWithQuestionType:questionType];
}
return self;
}
return [super init];
}
- (instancetype)init
{
NSLog(@"Init!");
return [self initWithQuestionType:@"unKnow"];
}
and then:
Question *question = [[Question alloc] initWithQuestionType:@"choice"];
the output is:
2015-10-16 20:58:50.278 initSample[3687:161396] **class:Question
2015-10-16 20:58:50.279 initSample[3687:161396] --class:(null)
2015-10-16 20:58:50.279 initSample[3687:161396] **class:Choice
2015-10-16 20:58:50.280 initSample[3687:161396] ++class:Choice
and I can't understand why [super init]
did not be executed?
Your [super init]
method is being called:
[Question initWithQuestionType]
is called.if
is true, so it's entered."choice"
so [Choice initWithQuestionType:]
is called.Choice
does not override -initWithQuestionType:
, this will call [Question initWithQuestionType:]
again.if
is false, so it's not entered, and [super init]
is being called.This is being shown in your log messages (add an another log call before the [super init]
method, to prove this).
However it's a very confusing and difficult to maintain factory method, and it's much easier to use a class factory method, as below. That way your init
methods will be much more straight-forward and easier to maintain.
+ (Question *)questionWithType:(NSString *)type
{
if ([type isEqualToString:@"choice"])
return [[Choice alloc] init];
else
return [[Blank alloc] init];
}
Also consider using an enum
to represent the type, rather than a string (quicker/more efficient).