Разница между объявлением @interface и объявлением @property
Я новичок в C, новичок в объекте C. Для подкласса iPhone Im, объявляющий переменные, я хочу быть видимым для всех методов в классе в определении класса @interface, например
@interface myclass : UIImageView {
int aVar;
}
а затем объявляю его снова как
@property int aVar;
И затем позже I
@synthesize aVar;
Можете ли вы помочь мне понять цель трех шагов? Я делаю что-то ненужное?
Спасибо.
Ответы
Ответ 1
Здесь вы объявляете переменную экземпляра с именем aVar
:
@interface myclass : UIImageView {
int aVar;
}
Теперь вы можете использовать эту переменную в своем классе:
aVar = 42;
NSLog(@"The Answer is %i.", aVar);
Однако переменные экземпляра являются частными в Objective-C. Что делать, если вам нужны другие классы для доступа и/или изменения aVar
? Поскольку методы общедоступны в Objective-C, ответ заключается в написании метода доступа (getter), который возвращает aVar
и метод mutator (setter), который устанавливает aVar
:
// In header (.h) file
- (int)aVar;
- (void)setAVar:(int)newAVar;
// In implementation (.m) file
- (int)aVar {
return aVar;
}
- (void)setAVar:(int)newAVar {
if (aVar != newAVar) {
aVar = newAVar;
}
}
Теперь другие классы могут получить и установить aVar
через:
[myclass aVar];
[myclass setAVar:24];
Написание этих методов доступа и мутаторов может стать довольно утомительным, поэтому в Objective-C 2.0 Apple упростила его для нас. Теперь мы можем написать:
// In header (.h) file
@property (nonatomic, assign) int aVar;
// In implementation (.m) file
@synthesize aVar;
... и методы accessor/mutator будут автоматически сгенерированы для нас.
Подводя итог:
-
int aVar;
объявляет переменную экземпляра aVar
-
@property (nonatomic, assign) int aVar;
объявляет методы доступа и мутатора для aVar
-
@synthesize aVar;
реализует методы доступа и мутатора для aVar
Ответ 2
Это объявляет переменную экземпляра в вашем объекте:
@interface myclass : UIImageView {
int aVar;
}
Экземпляры экземпляра - это частные детали реализации вашего класса.
Если вы хотите, чтобы другие объекты могли читать или устанавливать значение переменной экземпляра (ivar), вы можете объявить ее как свойство:
@property int aVar;
Это означает, что компилятор ожидает, что для свойства будут найдены методы доступа к установщику и getter.
Когда вы используете ключевое слово @synthesize, вы просите, чтобы компилятор автоматически генерировал методы доступа к сеттерам и getter для вас.
Итак, в этом случае компилятор сгенерирует код, подобный этому, когда он встретит ключевое слово @synthesize:
- (int) aVar
{
return aVar;
}
- (void)setAVar:(int)someInt
{
aVar = someInt;
}
По умолчанию на iPhone (и в 32-разрядной среде исполнения на Mac) @synthesize
требуется наличие экземпляра, чтобы сохранить значение свойства. Этот ivar обычно называют таким же, как и свойство, но не обязательно, например, вы могли бы сделать это:
@interface myclass : UIImageView {
int aVar;
}
@property int someValue;
@synthesize someValue = aVar;
Ни для того, ни для @synthesize
, ни для @property
, вы можете создать свои собственные методы getter и setter, и пока вы их создаете с использованием синтаксиса, совместимого с Key-Value Coding, свойство все равно будет использоваться.
Требование присутствия ivar, а также объявление @property
обусловлено хрупким базовым классом ограничение 32- бит Objective-C на Mac и iPhone. В 64-битной среде выполнения на Mac вам не нужен ivar, @synthesize
генерирует его для вас.
Обратите внимание, что имеется множество ключевых слов, которые вы можете использовать с объявлением @property
для управления каким-то синтезированным кодом доступа, например readonly
для аксессора getter-only, copy
, atomic
, nonatomic
и т.д. Дополнительная информация содержится в документации Objective-C 2.0 Programming Language.
Ответ 3
Классы могут иметь переменные экземпляра (ivars). Они находятся в первом разделе и видны только для кода в этом классе, а не для внешнего кода. Мне нравится префикс их подчёркивать, чтобы показать их внутренность. В условиях низкого уровня, ivars добавляются как дополнительный член в структуру, которую созданный вами класс использует внутри.
Второе объявление, @property, является объявленным свойством. Это не требуется (кроме случаев, когда вы используете @synthesize), но это помогает другим программистам (и компилятору!) Знать, что вы имеете дело с свойством, а не только с двумя методами -setAVar
и -aVar
, которые являются альтернативный способ сделать это.
В-третьих, @synthesize фактически создает методы для установки и доступа к свойству извне класса. Вы можете заменить это на свой собственный метод setter и getter, но только делайте это, если вам нужно, поскольку встроенные имеют некоторые функции, которые вам в противном случае пришлось бы закодировать самостоятельно. Фактически, используя синтаксис @synthesize aVar = _someVariable;
, вы можете иметь свое свойство, которое действительно ссылается на другую именованную переменную экземпляра!
Краткая версия:
@property - это просто подсказка для компилятора и других программистов, которые вы создаете свойство, а не только методы getter/setter. Переменные экземпляра являются внутренними для класса, и в противном случае он не может быть нормально доступен извне. @synthesize просто создает простые геттеры и сеттеры для вас, чтобы пойти с вашим @property, но вы также можете просто скопировать эти геттеры и сеттеры самостоятельно, как и любой другой метод.
Ответ 4
@interface объявляет экземпляры переменных класса в obj-c. Это необходимо для создания переменной экземпляра. Однако переменная не видна вне класса по умолчанию (поскольку по умолчанию защищено).
@property сообщает компилятору указать конкретный метод доступа к ресурсам (get/set). Однако вам нужно будет использовать @synthesize, чтобы на самом деле компилятор автоматически сгенерировал простые аксессоры, иначе вы должны создать их самостоятельно.
Ответ 5
Недавно я начал изучать приложения для iphone. По моим знаниям @property используется в файле .h как метод setter и @synthesize в .m файле как метод getter. В Java мы используем методы setter и getter, такие же как Java, в Objective C мы используем @property и @synthesize.
Пожалуйста, простите меня, если вы думаете, что я вас обманываю.
Ответ 6
Class A
@interface myclass : UIImageView {
int aVar;
}
If you declare like this then you can only use this variable within your class A.
But suppose in Class B
A *object=[A new];
object.aVar---->not available
For this you should **declare aVar as a property in Class A**
so class A should look like
Class A
@interface myclass : UIImageView {
int aVar;
}
@property int iVar;
and
.m file
@synthesize iVar;
So now you can use this iVar in another class Suppose B
Class B
#import "Class A.h"
enter code here
A *object=[A new];
object.aVar---->available
means
object.aVar=10;