Лучший способ предотвратить вызов других программистов -init
При разработке иерархии классов иногда подкласс добавляет новый метод initWithSomeNewParam
, и было бы желательно отключить вызовы к старому методу init
, унаследованному от суперкласса.
Прежде всего, я прочитал вопрос здесь, где предлагаемые альтернативы либо переопределяют init
, чтобы генерировать исключение во время выполнения, либо переопределять и устанавливать значения по умолчанию для свойств. В моем случае я не хочу предоставлять значения по умолчанию, и я хочу четко указать, что старый метод не следует вызывать, а вместо этого следует использовать новый метод с параметрами.
Таким образом, исключение во время выполнения прекрасно, но если код не отлаживается, нет никаких шансов для других программистов в команде заметить, что старый метод больше не предназначен для использования.
Если я прав, нет способа отметить метод как "private". Итак, помимо добавления комментариев, есть ли способ сделать это?
Спасибо заранее.
Ответы
Ответ 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
в экземпляре этого класса.
Ответ 3
Отметить, что он устарел?
Разработчики будут разработчиками, вы не сможете остановить нас всех!; -)
Как я могу отметить метод как устаревший в Objective-C 2.0?
Ответ 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 (а также к пометке, устаревшей в своих документах).