Objective-C Частная дилемма
Я знаю, что Objective-C не поддерживает реальные частные методы. То, что я сейчас делаю для объявления методов 'private', добавляет следующее в класс .m файлов:
@interface MyClass()
- (void) privateMethodName;
@end
Проблема:
Если я теперь добавлю подкласс и хочу использовать этот метод 'private', я не могу! Я получаю сообщение об ошибке:
Тип получателя "SubClassName" для сообщения экземпляра не объявляет метод с selector 'privateMethodName'
Итак, если я не хочу, чтобы не-подклассы имели доступ к этому методу, но хотите, чтобы подклассы могли это делать, что я могу сделать? Каков наилучший/правильный способ достижения моей цели?
Ответы
Ответ 1
Вы можете отделить "защищенный" интерфейс от общедоступного. В основном заголовке просто объявите общедоступные методы:
MyMagicThingy.h
:
@interface MyMagicThingy: NSObject
- (void) publicMethod;
@end
Затем добавьте дополнительный заголовок с защищенными методами:
MyMagicThingy+Protected.h
:
#import "MyMagicThingy.h"
@interface MyMagicThingy (Protected)
- (void) protectedMethods;
@end
У вас не может быть "реальных" частных/защищенных/общедоступных методов в Objective C (как в: компилятор будет применять правила доступа. Все методы общедоступны). Вы должны пойти с соглашением.
Ответ 2
То, что вы описываете, действительно является защищенным методом. Один из способов преодоления этого: Ivars можно объявить @public
, @protected
или @private
. Вы можете объявить защищенный вспомогательный экземпляр для ограничения доступа к производным экземплярам, который затем перезванивает объект, который его удерживает.
Еще одна альтернатива в некоторых случаях заключалась бы в том, чтобы подклассы записывали в интерфейс, а затем сохраняли вашу реализацию частной.
Иногда вам просто нужно документировать "не делайте этого, если вы не являетесь подклассом", потому что он не является частью языка. В этом мышлении отдельный заголовок, объявляющий категорию защищенных методов, является одним из моих любимых. Он довольно хорошо скрыт от клиентов, но может быть видимым для подклассов путем явного включения - Dirk представил пример этого в то же время, проверьте его.
Наконец, если вам нравится ObjС++, С++ предлагает этот элемент управления, поэтому вы можете свободно перемещать режимы и видимость.
Ответ 3
Прежде всего
Вы не можете заставить кого-либо не отвечать на любой метод, реализованный на объекте в Objective-C (по крайней мере, не без горения через несколько десятков бритв, что делает Якс менее защищенным от атмосферных воздействий).
Просто не вызывать методы, которые не объявлены в общедоступных файлах заголовков, как соглашение (это то, что вы уже делаете).
Второй
Слово public в приведенном выше параграфе делает трюк:
В Objective-C (по крайней мере, в его текущем воплощении) интерфейс класса можно определить по любому количеству файлов заголовков, используя технику, которую вы только что описали в своем сообщении: Продолжения классов.
Один из таких примеров класса инфраструктуры Apple, который делает это, будет UIGestureRecognizer
с его отдельным заголовком подкласса UIGestureRecognizerSubclass.h
.
PS:
Ошибка, которую вы видите во время использования ARC, поэтому ваша среда исполнения определенно достаточно недавно, чтобы даже использовать для нее несколько файлов реализации.