为什么我的代码没有进入 [super init] 函数?

Why my code did not get into [super init] function?

有classQuestionChoiceBlank三个,Question是[=14=的超class ] 和 Blank.

然后,我写了一些方法如下:

- (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"];
}

然后:

Question *question = [[Question alloc] initWithQuestionType:@"choice"];

输出为:

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

我不明白为什么[super init]没有被执行?

正在调用您的 [super init] 方法:

  1. [Question initWithQuestionType] 被调用。
  2. 第一个if为真,所以输入。
  3. 题型是"choice"所以叫[Choice initWithQuestionType:]
  4. 由于 Choice 没有覆盖 -initWithQuestionType:,这将再次调用 [Question initWithQuestionType:]
  5. 这次if为false,所以没有输入,正在调用[super init]

这显示在您的日志消息中(在 [super init] 方法之前添加另一个日志调用,以证明这一点)。

然而,工厂方法是一个非常混乱和难以维护的方法,使用 class 工厂方法要容易得多,如下所示。这样您的 init 方法将更加直接和易于维护。

+ (Question *)questionWithType:(NSString *)type
{
    if ([type isEqualToString:@"choice"])
        return [[Choice alloc] init];
    else
        return [[Blank alloc] init];
}

还可以考虑使用 enum 来表示类型,而不是字符串(quicker/more 有效)。