Подтвердить что ты не робот

Objective-c - вызов одного конструктора из другого

Скажем, у вас были следующие два конструктора:

- (id)initWithTitle:(NSString *)title;
- (id)initWithTitle:(NSString *)title page:(NSString *)page;

Второй конструктор ничем не отличается от первого, за исключением того, что он устанавливает переменную-член "страница".

Поскольку он в основном должен делать то же самое, есть ли способ вызвать первый из второго, чтобы уменьшить дублирование кода, или вам нужно настроить третий метод для выполнения общих задач?

Я говорю о чем-то подобном, хотя я сомневаюсь, что это сработает:

- (id)initWithTitle:(NSString *)_title {
    if(self = [super init]) {
        self.title = _title;
    }

    return self;
}

- (id)initWithTitle:(NSString *)_title page:(NSString *)_page {
     if(self = [self initWithTitle:_title]) {
         self.page = _page;
     }

     return self;
}
4b9b3361

Ответ 1

То, что вы говорите, странно, потому что я думаю об этом

- (id)initWithTitle:(NSString *)_title {
    return [self initWithTitle:_title page:nil];
}

- (id)initWithTitle:(NSString *)_title page:(NSString *)_page {
    if(self = [super init]) {
        self.title = _title;
        self.page = _page;
    }
    return self;
}

Не работает ли он?

Ответ 2

Во-первых, у вас нет конструкторов, у вас есть два инициализатора:

- (id)initWithTitle:(NSString *)title;
- (id)initWithTitle:(NSString *)title page:(NSString *)page;

Как и в большинстве инициализаторов, целью является настройка некоторых переменных экземпляра (не переменных-членов).

Первый шаг - идентифицировать назначенный инициализатор. В вашем случае это может быть:

- (id)initWithTitle:(NSString *)title page:(NSString *)page;

Это означает, что - (id)initWithTitle:(NSString *)title; будет реализован, как описано другими:

- (id)initWithTitle:(NSString *)_title {
    return [self initWithTitle:_title page:nil];
}

Однако я бы рекомендовал против этого шаблона, поскольку он делает подкласс более подверженным ошибкам, чем должен быть. В подклассе вы должны всегда переопределять назначенный инициализатор, или вы должны реализовать новый инициализатор, который вызывает назначенный инициализатор. Очевидно, чем больше инициализаторов у вас есть, тем больше возможностей для ошибок в подклассе вы можете ввести.

Кроме того, это:

Foo *f = [[Foo alloc] initWithTitle: @"Foo!" page: nil];

Яснее, чем это:

Foo *f = [[Foo alloc] initWithTitle: @"Foo!"];

Первое указывает на то, что вы подумали о page и решили явно установить его на nil или иначе полагаться на класс Foo, чтобы установить страницу разумно. Второй не дает такого указания.

Оба подкласса и явное указание намерения являются основными причинами, по которым вы найдете недостаток таких методов удобства в Cocoa (есть некоторые, но большинство из них довольно старые - старше, чем когда политика действительно стала правилом).