Когда вы НЕ хотите использовать переменные экземпляра @synthesized? - PullRequest
4 голосов
/ 07 декабря 2010

В среде выполнения Modern Objective C вы можете сделать что-то вроде этого:

@interface MyClass : NSObject {
}
@property NSString *stringProperty;
@end

@implementation MyClass
@synthesize stringProperty;
@end

Насколько я понимаю, в современной среде выполнения это будет не только синтезировать методы доступа для моего свойства, но и саму переменную экземпляра, так что я мог бы затем сказать в одном из методов этого класса [stringProperty length];, и он будет работать так, как если Я объявил переменную экземпляра.

Я начал использовать это во всем своем коде сейчас, потому что, ну, это еще одна вещь, которую я должен писать снова и снова. И я слышал с помощью компилятора clang 2.0, я даже смогу пропустить @synthesize (но это другое дело). Но мне было интересно, каковы некоторые недостатки этого? Когда мне действительно понадобится переменная экземпляра в дополнение к моим свойствам?

Я знаю, что иногда мне хочется сохранить переменную приватной и не предоставлять ей доступ извне (но тогда я обычно просто объявляю свойство в своем расширении частного класса, или я вообще не создаю для него свойство , если мне не нужны средства для этого).

Бывают ли случаи, когда я бы не хотел этого делать?

Ответы [ 5 ]

4 голосов
/ 08 декабря 2010

Одна из возможных причин, по которой целесообразно не использовать синтезированные переменные экземпляра, заключается в том, что в текущей версии Xcode (3.2.5) их немного труднее отлаживать.Похоже, они не отображаются в режиме live debugger при запуске кода через GDB, единственный способ получить их - через консоль gdb, например po [0xOBJ_ADDRESS propertyName].Не совсем так хорошо, как стандартный несинтезированный ivar.

Возможно, Xcode 4 исправляет это, но у меня недостаточно опыта, чтобы сказать (и он все еще под NDA).

Больше информации по этому вопросу SO: Просмотр значения синтезированного свойства в отладчике Xcode, когда нет резервной переменной

3 голосов
/ 08 декабря 2010

Может потребоваться предоставить множество свойств для одной переменной экземпляра, например:

  • для доступа к значению угла в градусах и радианах
  • для доступа к координатам как в прямоугольной формеи в полярных системах

В этих случаях вам не нужно ни синтезировать переменные экземпляра (они уже существуют), ни методы доступа (вы хотите предоставить их для выполнения преобразований).

1 голос
/ 08 декабря 2010

Но мне было интересно, каковы некоторые недостатки этого? Когда мне действительно понадобится переменная экземпляра в дополнение к моим свойствам?

Возможные причины:

  • позволяет изменять переменную экземпляра в init и dealloc без отключения переопределений подкласса или KVO.
  • приложение будет компилироваться и запускаться в 32-битном режиме на Mac OS X. Есть еще некоторые Intel Mac, которые не поддерживают 64-битные.

Я не уверен, насколько верным является первый пункт. Там могут быть другие пути решения проблем. Второй момент - игра окончена, если вам нужно поддерживать старые Mac.

1 голос
/ 08 декабря 2010

В любое время вам нужно выполнить преобразование (если кто-то не знает лучшего способа) в классе, который нужно сериализовать. Например, если у вас есть класс с числовым значением. Вы не можете сериализовать целое число, поэтому сохраняете его как NSNumber в классе, но свойство имеет целочисленный тип.

Другой пример, если вы кодируете, как рекомендует Apple, при работе с CoreData. Они говорят, что вы должны создать пользовательский класс, производный от NSManagedObject, в качестве класса для вашего управляемого объекта и использовать свойство для каждого атрибута. Тогда вы бы использовали @dynamic вместо @synthesize, и iVar вообще не нужен.

0 голосов
/ 08 декабря 2010

Еще одна причина - избегать ярлыков для прямого доступа к переменным.

Я стараюсь следовать соглашению о персональном кодировании: - переменная объекта: префикс с подчеркиванием '_xxx' - свойство: имя без подчеркивания 'xxx'

Это гарантирует, что я никогда не напишу непреднамеренно что-то вроде

xxx = value;

или

[xxx someMessage];

Я хочу всегда использовать метод получения / установки.

self.xxx = value;
[self.xxx someMessage];

Это особенно полезно, когда вы используете ленивый init для переменных объекта ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...