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

Лучший способ предотвратить вызов других программистов -init

При разработке иерархии классов иногда подкласс добавляет новый метод initWithSomeNewParam, и было бы желательно отключить вызовы к старому методу init, унаследованному от суперкласса.

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

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

Если я прав, нет способа отметить метод как "private". Итак, помимо добавления комментариев, есть ли способ сделать это?

Спасибо заранее.

4b9b3361

Ответ 1

Вы можете явно указать свой init как недоступный в своем файле заголовка:

- (id) init __unavailable;

или

- (id) init __attribute__((unavailable));

С более поздним синтаксисом вы можете даже указать причину:

- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));

Затем компилятор выдает ошибку (а не предупреждение), если кто-то пытается ее вызвать.

Ответ 2

Чтобы добавить к сообщению @DarkDust, вы можете использовать UNAVAILABLE_ATTRIBUTE

- (id)init UNAVAILABLE_ATTRIBUTE;

Это вызовет ошибку, когда пользователь попытается вызвать init в экземпляре этого класса.

Ответ 4

initWith: Stuff и: OtherStuff никогда не должны быть больше, чем конструкторы удобства.

В том, что они эффективно должны вызывать

self = [self init];

if(self)
{
    self.stuff = Stuff;
    self.other = OtherStuff;
}

поэтому [object init] всегда будет возвращать объект в предопределенном состоянии, а [объект initWithStuff: stuff] возвращает объект в предопределенном состоянии с переопределенным материалом.

В основном то, что я получаю, это его плохая практика, чтобы препятствовать [объекту init], особенно когда кто-то подклассифицирует ваш подкласс в будущем...

Ответ 5

Вы можете сортировать меток как "private", указав личное расширение в свой класс.

В вашем .h:

@interface MyClassName
- (void)initWithSomeNewParam:(id)param;

В вашем .m:

@interface MyClassName ()
- (void)init;
@end

Вы также можете добавить оператор NSLog, чтобы при запуске проекта с подключенным сеансом XCode они отображали консольный вывод, похожий на "Пожалуйста, не используйте init, используйте initWithSomeNewParam: вместо этого." Обратите внимание, что это тот подход, который сам Apple исторически принял к устаревшим вызовам API (а также к пометке, устаревшей в своих документах).