Переопределение имени свойства синтеза Objective-C

StackOverflow https://stackoverflow.com/questions/3802851

  •  25-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь понять цель synthesize директива с переопределением имени свойства.Скажем, у меня есть интерфейс, определенный следующим образом:

@interface Dummy ... {
    UILabel *_dummyLabel;
}

@property (retain, nonatomic) UILabel *dummyLabel;

И в файле реализации у меня есть:

@synthesize dummyLabel = _dummyLabel;

Насколько я понимаю, «dummyLabel» — это просто псевдоним переменной экземпляра «_dummyLabel».Есть ли разница между self._dummyLabel и self.dummyLabel?

Это было полезно?

Решение

да. self._dummyLabel не определено, однако _dummyLabel не является.

Точечный синтаксис расширяется до простых вызовов метода, поэтому он не специфичен для свойств. Если у вас есть метод под названием -(id)someObject, например, в случае object.someObject, Будет так, как будто вы написали [object someObject];.

self.dummyLabel  //works
self._dummyLabel //does not work
dummyLabel       //does not work
_dummyLabel      //works
[self dummyLabel];  //works
[self _dummyLabel]; //does not work

Другие советы

Ваше понимание неверно. dummyLabel это название собственности и нет псевдоним для переменной экземпляра - переменная экземпляра Только называется _dummyLabel. Отказ Так что следующие проводятся для экземпляра Dummy называется myObject:

  • [myObject dummyLabel] работает
  • myObject.dummyLabel работает
  • [myObject _dummyLabel] Не удается
  • myObject._dummyLabel Не удается
  • myObject->dummyLabel Не удается
  • myObject->_dummyLabel зависит от видимости Ивара (@public, @private, @protected)
  • [myObject valueForKey: @"dummyLabel"] работает
  • [myObject valueForKey: @"_dummyLabel"] зависит от реализации +accessInstanceVariablesDirectly (т.е. это будет работать в случае по умолчанию, где +accessInstanceVariablesDirectly возвращается YES).

Преимущество наличия другого имени для Ивара, чем для собственности, заключается в том, что вы можете легко увидеть в коде, когда вы получаете доступ к одному или другому - Andre K

Я не могу найти кнопку «комментарий», поэтому я должен публиковать как «ответ».

Просто хотел расширить комментарий Andre - знаком, когда вы используете синтезированные свойства, против ванильной переменной, вы знаете (особенно в случае с больницами), когда переменная сохраняется / копируется / выпущена автоматически благодаря вашему приятному сеттелю, VS манипулировать вручную.

Конечно, если вы делаете все правильно, вам, вероятно, не нужна помощь сеттера, чтобы исправить / высвобождать объекты правильно! Но тоже могут быть другие сценарии, где относятся к вашим иверам как self.ivar вместо _ivar Может быть полезен, например, когда вы используете пользовательские посетители / GetTers вместо синтезированных по умолчанию. Возможно, каждый раз, когда вы измените свойство, вы также хотите хранить его в NsuserDefaults. Таким образом, у вас может быть такой код:

@interface SOUserSettings : NSObject {

BOOL _autoLoginOn;

}

@property (nonatomic, assign) BOOL autoLoginOn;

@end

@implementation SOUserSettings

@synthesize autoLoginOn = _autoLoginOn;

- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {

   _autoLoginOn = newAutoLoginOnValue;
   [[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:@"UserPrefAutoLoginOn"];
}

@end

Примечание: это просто иллюстративный код, с ним может быть тысяча вещей!

Так что теперь в вашем коде, если у вас есть строка, которая говорит _autoLoginOn = YES - Вы знаете, что это не будет сохранено в NsuserDefaults, тогда как если вы используете self.autoLoginOn = YES Вы точно знаете, что произойдет.

Разница между _autoLoginOn а также self.autoLoginOn это больше, чем просто семантика.

Я не вижу никаких больших преимуществ переименования _DummyLabel в Dummylabel

В некоторых objc runtimes у вас есть трудные временные переменные экземпляра невидимы для пользователей класса. Для них придерживаясь префикса (или суффикса) на вашу переменные экземпляра, может сделать его понятным (или более понятным), что вы не хотите, чтобы кто-то не возился с вашими переменными. Однако вы не хотите, чтобы этот ганк на ваших публичных функциях. Это позволяет вам сделать это.

Он также может быть полезен, если вам нужно будет поддерживать старый интерфейс с одним набором имен одновременно с новым набором API с новым набором имен (SetLastname vs. Setsonname).

Старый пост, но я считаю важным отметить, что доступ к переменным рекомендуется осуществлять через геттеры и сеттеры (то есть с помощью точечной записи).Доступ к полю напрямую (_ivar) настоятельно рекомендуется только при его инициализации.

Есть хорошая статья Apple:https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatedData/EncapsulatedData.html

Последний абзац:

Вы всегда должны обращаться к переменным экземпляра непосредственно изнутри initialization, потому что в момент установки свойства Остальная часть объекта может быть еще не полностью инициализирована.Даже если вы не предоставляйте пользовательские методы доступа и не знайте о каких-либо побочных эффектах от В вашем собственном классе будущий подкласс вполне может переопределить поведение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top