-4

共有三个类QuestionChoiceand Blank,and是andQuestion的超类。ChoiceBlank

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

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

输出为:</p>

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]没有被处决?

4

1 回答 1

0

您的[super init]方法被调用:

  1. [Question initWithQuestionType]叫做。
  2. 第一个if是真的,所以它被输入了。
  3. 问题类型就是"choice"所谓[Choice initWithQuestionType:]的。
  4. 由于Choice不覆盖-initWithQuestionType:,这将[Question initWithQuestionType:]再次调用。
  5. 这次if是假的,所以它没有被输入,[super init]正在被调用。

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

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

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

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

于 2015-10-16T14:16:11.137 回答