Objective-C: Почему бы не вызвать назначенный инициализатор?

Я унаследовал этот код:

- (id)initWithLocation:(CLLocation *)inLocation {
    if (self = [super init])
    {
        _location = [inLocation copy];
    }
    return self;
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init])
    {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

и мне интересно, есть ли веская причина, по которой первый метод не вызывает назначенный инициализатор (например, как этот Можно ли вызывать метод инициализации в самом себе, в методе инициализации?)?

то есть почему бы не сделать так:

- (id)initWithLocation:(CLLocation *)inLocation {
    if (self = [super init])
    {
        [self initWithLocation:inLocation offsetValue:nil];
    }
    return self;
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init])
    {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

person Snowcrash    schedule 26.02.2015    source источник


Ответы (3)


Метод - (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset должен быть назначенным инициализатором, а - (id)initWithLocation:(CLLocation *)inLocation должен вызывать его следующим образом:

- (id)initWithLocation:(CLLocation *)inLocation {
    return [self initWithLocation:inLocation offsetValue:nil];
}

Также считается хорошей практикой помечать назначенный инициализатор в интерфейсе класса с помощью NS_DESIGNATED_INITIALIZER:

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset NS_DESIGNATED_INITIALIZER;
person kean    schedule 26.02.2015
comment
Учитывая, что все ответы почти одинаковы, я выбираю этот, поскольку в нем упоминается NS_DESIGNATED_INITIALIZER. - person Snowcrash; 26.02.2015

гораздо более подходящий способ был бы таким:

- (id)initWithLocation:(CLLocation *)inLocation {
    return [self initWithLocation:inLocation offsetValue:nil];
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init]) {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}
person holex    schedule 26.02.2015

Все, что вам действительно нужно сделать, это...

- (id)initWithLocation:(CLLocation *)inLocation {
    return [self initWithLocation:inLocation offsetValue:nil];
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init])
    {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

И ты прав. В данном случае нет причин не делать этого.

person Fogmeister    schedule 26.02.2015