Я могу понять определение функций в @interface файла заголовка, но почему переменные экземпляра? Должны ли переменные экземпляра быть закрытыми, доступными только через сообщения?Почему переменные экземпляра определены в файле заголовка в Objective-C
ответ
Причина в том, что он может вычислять смещения переменных для подклассов.
@interface Bird : NSObject {
int wingspan;
}
@end
@interface Penguin : Bird {
NSPoint nestLocation;
Penguin *mate;
}
@end
Не зная структуру класса «Bird», класс «Пингвин» не может вычислить смещение ее поля от начала структуры. Структура пингвинов выглядит вроде как это:
struct Penguin {
int refcount; // from NSObject
int wingspan; // from Bird
NSPoint nestLocation; // from Penguin
Penguin *mate; // from Penguin
}
Это имеет побочный эффект: если вы измените размер класса в библиотеке, вы нарушаете все подклассы в приложениях, которые ссылаются на эту библиотеку. Эта проблема связана с новыми свойствами.
Несмотря на то, что они объявлены в файле заголовка, все переменные экземпляра в Objective-C по умолчанию имеют защищенный доступ @protected. Это означает, что переменная доступна в классе, который объявляет его и любой класс, наследующий от этого класса.
Вот документация Apple, по определению класса Objective-C: Defining Classes
Обратите внимание на раздел под названием «Сфера переменного экземпляра».
Взятые из раздела документации Apple, по определению классов Objective-C, The Role of the Interface:
Although instance variables are most naturally viewed as a matter of the implementation of a class rather than its interface, they must nevertheless be declared in the interface file. This is because the compiler must be aware of the structure of an object where it’s used, not just where it’s defined.
Я думаю, что это технический вопрос. Если я правильно понимаю, класс Objective-C - просто причудливая структура C. И для структуры, которую нужно использовать, ее размер должен быть известен. (Как, например, как будет работать sizeof())
Обратите внимание, что в рамках нового «Современного времени выполнения» Objective C 2.0 (доступного в приложениях iPhone и 64-разрядных приложениях Mac OS X 10.5) вам не нужно указывать ивары, вы можете указать свойства, а затем использовать @synthesize для генерации ivars.
Это связано с тем, что в современной среде исполнения ivars имеет символ глобальной косвенности, который содержит смещение для ivar. Это также устраняет проблему хрупкого базового класса, позволяя переупорядочивать и добавлять ivars без необходимости перекомпиляции подклассов (удаление или переименование ivars может по-прежнему вызывать ошибки ссылок).
Однако вам по-прежнему нужно перечислить свойства в главном интерфейсе, поэтому, похоже, нет никакого способа полностью скрыть частные ивары, что является неудачным. Вы не можете, например, использовать свойство и @synthesize в категории.
Вы можете, однако, объявить свойство в продолжении и @synthesize в главном @implementation. –
В случае, если кто натыкается этим вопрос - по состоянию на XCode 4.2 с компилятором LLVM, вы можете объявить переменный экземпляр в @implementation с помощью следующей распорки обозначения:
@interface SomeClass : NSObject
@end
@implementation SomeClass {
NSString *myInstanceVariable_;
}
- (void)moreMethods {}
@end
переменных экземпляра вообще не должен быть частью ваших классов, объявленных публичным интерфейсом - это детали реализации.
Однако УБЕДИТЕСЬ вы определяете переменные экземпляра в фигурных скобках, иначе вы будете определения глобальной переменной, которая не имеет никакого отношения к экземпляру объекта:
@implementation SomeClass
NSString *whoopsGlobalVariable_;
- (void)moreMethods {}
@end
Я только что изучал это. Кажется, из моего тестирования пока что GCC не сделает этого; он дает ошибку: «несогласованная спецификация переменных экземпляра». Он только компилируется с LLVM. См. Также [Объявление переменных в @implementation] (http://stackoverflow.com/questions/7946998/declaring-variables-in-implementation). –
Правильно, для этого нужен современный компилятор LLVM. – sickp
- 1. Почему обе переменные не определены?
- 2. Почему некоторые переменные не определены?
- 3. Почему переменные не определены в контроллере?
- 4. Почему мои переменные не определены?
- 5. Почему я должен определять переменные дважды в файле заголовка?
- 6. Почему глобальные переменные в файле заголовка вызывают ошибку ссылки?
- 7. Определены ли переменные в требуемом файле, недоступном снаружи?
- 8. Почему пространство имен требуется в файле заголовка?
- 9. Реальные переменные экземпляра в файле .js.erb
- 10. Как определить переменные в файле заголовка, C
- 11. xcopy не распознается, когда переменные определены в пакетном файле
- 12. Почему переменная в файле заголовка дает ошибку?
- 13. Почему свойства моего экземпляра не определены?
- 14. Почему переменные экземпляра не определены в методах контроллера, доступных в соответствующих частях?
- 15. Переменные экземпляра экземпляра и переменные экземпляра в Ruby
- 16. Проверяется переменные определены в Makefile
- 17. Мои переменные не определены?
- 18. Переменные экземпляра в представлении
- 19. Почему переменные экземпляра в рельсах имеют символ @?
- 20. переменные экземпляра в объекте c .m file
- 21. Javascript: некоторые переменные определены, некоторые не определены
- 22. WX_DECLARE_HASH_MAP в файле заголовка
- 23. Я объявляю все переменные экземпляра в файле .h в ObjC?
- 24. Переменные Javascript не определены
- 25. Почему переменные не определены внутри include, определенных в массиве $ GLOBALS?
- 26. переменные не определены в моем втором методе
- 27. Переменные экземпляра недоступны в подклассах ..?
- 28. Класс в файле заголовка
- 29. Переменные в файле CSS
- 30. Переменные экземпляра в webservice
Они просто C Структуры , даже не причудливые :-) так что-то вроде anObject-> anIVar работает отлично. К сожалению, устаревшая среда выполнения допускает такой доступ даже по переменным @private и просто рвет предупреждение компилятора: -/ –