Как отдельный экземпляр переменной?
Я хочу сделать переменную экземпляра, к которой нельзя получить доступ извне. Возможно ли что-то подобное в objective-c? Я помню, что у Apple есть частные переменные и тому подобное, но если люди знают о них, они могут их использовать. Apple называет это "частным API", но, очевидно, другие могут получить доступ, если они узнают, что там.
до сих пор я считал, что что-то вроде этого создает частный экземпляр переменной:
@interface MyClass : NSObject {
CGFloat weight;
}
нет свойство@, нет @синтезировать, просто объявление выше.
также Я знаю, что Apple добавляет _inFrontOfTheirPrivateInstanceVariables, но они где-то сказали, что им не нравится, когда другие делают это, потому что они могут переопределить случайно скрытые переменные экземпляра при этом.
в чем тут фишка?
7 ответов:
можно использовать
@private
ключевое слово внутри{}
чтобы сделать все последующие объявления переменных частная. Видимость по умолчанию:@protected
(что похоже наprotected
в Java), и это, как правило, работает хорошо. Вы должны были бы специально объявить переменную как@public
чтобы он был непосредственно доступен за пределами класса.это документация Apple имеет более подробную информацию о переменной области и видимости.
существует также разница между "частный API" и частные переменные. В Objective-C вы не можете сделать методы частными - любой может вызвать любой метод. Есть несколько способов создания "секретных" методов, но это несколько выходит за рамки этого вопроса. Вот несколько связанных с этим вопросов:
- о частных переменных экземпляра в Objective-C
- что означает "@private " в Objective-C?
- можно ли объявить метод, как частный в Objective-C?
- лучший способ определить частные методы для класса в Objective-C
Что касается ведущего _ перед переменными, имейте в виду, что Apple также оставляет этот префикс для "частных" методов. Лучший способ избежать проблем-использовать обычные соглашения об именах для собственных переменных и методов. Однако, если вы не разделяете что-то от какао (кроме NSObject) вы можете быть уверены, что вы не будет сталкиваться с проблемами.
С новым компилятором LLVM, доступным в XCode 4 и более поздних версиях, вы можете объявить
@private
переменные в категориях по умолчанию внутри вашей реализации (.файл м):@interface ClassName() { @private // private variables here } @end @implementation ClassName // you can use private variables here @end
Я нахожу это удобным, так как я ненавижу загрязнение частных переменных, вносимых в мои заголовочные файлы.
вы можете определить частные методы, просто имея их только в @реализации, а не в @интерфейс.
аналогично, вы можете определить частные переменные экземпляра внутри анонимного блока в начале реализации @ - как вы делаете для публичных Ивар внутри интерфейса@.
рассмотрим следующий пример.
@interface EXClass : NSObject { uint8_t publicInteger; float publicFloat; } -(void)publicMethod; @end @implementation EXClass { uint8_t privateInteger; float privatefloat; } -(BOOL)privateMethod { return FALSE; }
помните, что методы objective-C отправляются как сообщения во время выполнения (а не привязка времени компиляции C++), поэтому respondsToSelector: все равно вернет true и performSelector: все равно вызовет метод. Ивары будут полностью приватны.
если бы вы делали библиотеку, теоретически никто не знал бы о каких-либо методах, которые вы не объявили в заголовочных файлах.
все ивары в Objective-C защищены по умолчанию. Если вы не пишете методы доступа, то другие классы не смогут видеть переменные.
двумя исключениями являются категории и подклассы.
Apple docs для именования переменных экземпляра явно не предупреждает об использовании подчеркивания в имени переменных экземпляра, как это делают документы частного метода.
именование переменных экземпляра и типов данных
Я также помню разговор между Уилом Шипли и несколькими другими разработчиками OS X, касающимися подчеркивания. Из-за того, как работает компилятор Obj-C, если Apple добавит новую переменную экземпляра в класс в своих рамках, это это приведет к необходимости перекомпиляции всех приложений, использующих эти фреймворки. Что касается уже существующих переменных экземпляра, вы должны получить предупреждение, когда вы наступите на один.
Я видел следующее использование в примере приложения (PaintGL) от Apple
In .файл м
@interface MyClass (private) - (void) privateMethod(); @property(...) myProperty; @end
отказ от ответственности: пример приложения имеет только объявления методов, я видел объявление частной собственности в потоке
вы можете не сделать реальную переменную частного экземпляра. Objective-C является динамическим языком, и поэтому можно получить доступ к любой переменной (даже @private).
мой лучший подход:
использовать его в блоке реализации .m-файл. Тогда не видно и блок KVC, так что KVC не будет работать
@implementation ClassName { // default to @protected // but the subclasses can't see ivars created in the implementation block float number; } + (BOOL)accessInstanceVariablesDirectly { return NO; // no KVC } @end