Почему мой код не попал в функцию [super init]?

Есть три класса Question,Choiceа также Blank,а также Question это супер класс Choice а также 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] не был выполнен?

1 ответ

Решение

Ваш [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];
}

Также рассмотрите возможность использования enum представлять тип, а не строку (быстрее / эффективнее).

Другие вопросы по тегам