#ios #instance-variables
#iOS #переменные экземпляра
Вопрос:
Может кто-нибудь объяснить мне значение создания (того, что кажется) дополнительной переменной и зачем ставить символ подчеркивания перед новой переменной с тем же именем, что и у последней.
Я читал, что это связано с созданием переменных экземпляра, но зачем вам создавать элемент пользовательского интерфейса в качестве переменной экземпляра? Не могли бы вы предоставить пример использования?
Это код objective c для использования в разработке iOS.
Спасибо.
Ответ №1:
Когда вы @synthesize
задаете свойство и не предоставляете свои собственные методы получения и установки (в этом случае в этом нет необходимости @synthesize
), всегда создается новая переменная экземпляра. По умолчанию он получает то же имя, что и свойство. Так @synthesize slider;
создается переменная экземпляра с именем slider
за кулисами.
Проблема здесь в том, что вы можете ошибочно ввести slider = xxx
, когда вы действительно хотели использовать self.slider = xxx
. Когда вы делаете что-то свойством, в рекомендациях говорится, что вы всегда должны обращаться к нему через self.propertyName
(за исключением ваших методов init и dealloc и любых пользовательских методов получения и установки).
Итак, чтобы избежать этого, @synthesize
оператор используется для переименования резервного ивара во что-то, что сложнее спутать со свойством. Если вы теперь используете slider
вместо self.slider
, компилятор выдаст сообщение об ошибке, потому slider
что это больше не имя переменной экземпляра.
Комментарии:
1. «Когда вы делаете что-то свойством, лучшая практика гласит, что вы всегда должны обращаться к нему через self.propertyName» — почему это лучшая практика?
2. Потому что в этом суть свойств, что вы всегда проходите через их методы доступа. Получая прямой доступ к ivars, вы обходите это поведение.
Ответ №2:
Причина этого заключается в том, чтобы сделать переменную экземпляра четко выделяющейся из синтаксиса разметки свойств. Это также имеет практический эффект, позволяющий избежать затенения переменных экземпляра из имен аргументов, которые также встречаются в некоторых ситуациях.
Причина использования переменной экземпляра вообще в большинстве случаев заключается в том, чтобы избежать запуска KVO при освобождении. Если вы сделаете это, вы рискуете запустить KVO таким образом, что ваши наблюдатели получат освобожденный объект, переданный им, вызывая EXC_BAD_ACCESS .
- (void)dealloc
{
self.slider = nil;
[super dealloc];
}
Поэтому обычно это делается вместо этого, что не вызовет KVO, поскольку вы не выполняете доступ к свойствам.
- (void)dealloc
{
[_slider release];
[super dealloc];
}
Ответ №3:
Это обычно используется для синтеза свойства с частным префиксом или суффиксом ivar. Он пытается предотвратить случайный доступ к ivar, а не к свойству или переопределение ivar с помощью аргумента метода.
Рассмотрим это:
@implementation MYClass
@synthesize flag = flag_;
- (void)doSomethingWithFlag:(BOOL)flag {
if (flag) {
// You do not need to worry about confusing the ivar
// flag and the param flag because it is synthesized to flag_
}
}
- (void)doSomething {
if (flag) { // Doesn't work -> use accessor self.flag
...
}
}
@end