Добавление переменных-членов в Objective C

#objective-c

#objective-c

Вопрос:

Сначала я должен сделать

 @property (retain) aMember;
  

Затем в файле реализации я должен сделать

 @synthesize aMember;
  

Затем в dealloc я должен сделать

 self.aMember= nil; (or [aMember release])
  

Это 3 раза, когда пишется то, что по сути является одним и тем же

Есть ли способ ускорить это?

Я имею в виду, что я могу перетащить элемент управления из IB, и xcode автоматически сгенерирует эти коды, почему я не могу сделать это для более обычных кодов?

Комментарии:

1. Насколько я знаю, это невозможно. Кроме того, не каждому элементу из IB нужна переменная для его обработки. Мы все знаем, что это дерьмовый процесс, но так оно и есть.

Ответ №1:

Как человек, знакомый с C # и управляемыми языками для моей повседневной работы, я полностью согласен с вами в вопросе этого трехэтапного процесса. На самом деле создавать свойства на C # в MS Visual Studio почти безумно просто, но я отвлекся.

Несмотря на то, что вам нужно написать эти 3 строки, под прикрытием вашего.

  1. Ваше объявление @property сообщает objective-c некоторые важные атрибуты (атомарный, неатомный, сохранение, копирование и т.д.) О том, как обращаться с вашим свойством, когда оно устанавливается пользователями вашего класса. Когда вы думаете об этом, эти атрибуты (без написания вами какого-либо кода) помогают вам создавать потокобезопасный код, обрабатывать ссылки на объекты, чтобы вам не приходилось беспокоиться о том, что они исчезнут у вас, или копировать значения, чтобы у вас была собственная копия объекта. Свойство @ также важно, поскольку оно объявлено в вашем заголовочном файле (обычно). Это дает другим разработчикам представление о свойствах вашего класса и несколько небольших подсказок относительно того, как объекты, которые они передают в эти свойства, будут обрабатываться в течение его жизненного цикла.

  2. @synthesize также выполняет довольно большую работу, создавая средства получения и настройки для этого свойства, которые также обрабатывают все виды управления памятью для вас. Вам не нужно беспокоиться о том, чтобы удалить старые ссылки и правильно ссылаться на новый объект. Для меня это само по себе отличная функция, особенно когда вы новичок в objective-c и легко забыть разобраться с управлением памятью на каждом шагу. @synthesize просто делает это за вас, и вам не нужно писать весь код get и set самостоятельно.

  3. Вызов dealloc — это просто жизнь в среде, не управляемой памятью. Хотя это добавляет дополнительные шаги, я ценю преимущества, которые дает явное управление памятью в ограниченной среде, такой как телефон.

Итак, требуются все 3 шага, они разные и, если подумать, на самом деле выполняют за вас довольно много работы под прикрытием.

Комментарии:

1. Есть ли, скажем, в окне редактора меню Add Property для генерации этих кодов.

2. Я понимаю, что все еще сложнее.

Ответ №2:

К сожалению, так оно и есть (на данный момент). Apple недавно поиграла с тем, чтобы разрешить Clang неявно синтезировать ваши свойства, что сократило бы вашу работу до:

 @interface Blah : NSObject
@property (retain) Blorg *blorg;
@end

@implementation Blah

- (void)dealloc {
  [blorg release];
  [super dealloc];
}

@end
  

Если вы не хотите, чтобы переменная экземпляра синтезировалась, вы бы просто явно поместили @dynamic blorg в свою реализацию. Но эта функция была удалена из-за некоторых непредвиденных осложнений, несмотря на в основном положительные реакции разработчиков.

Итак, я думаю, можно с уверенностью ожидать, что Apple все еще работает над этим. Но на данный момент вам действительно нужно явно синтезировать.

Несколько других замечаний:

  1. Если вы используете сборку мусора, вам не нужно внедрять -dealloc : просто убедитесь, что выполняете любую очистку в последнюю минуту в -finalize (например, отменяете регистрацию уведомлений).

  2. Вы также могли бы избежать этого -dealloc бита, заключив переменную вашего экземпляра в класс C , который выполняет управление памятью во время построения и уничтожения: @property prop_wrapper<Blorg> blorg; сработало бы. Затем, когда ваш объект будет уничтожен, ~prop_wrapper() будет вызван для вашего объекта. Я сделал это, и это работает, но я не рекомендую этого делать, поскольку это плохо сочетается с KVO и KVC.

  3. Вы могли бы перебирать свойства объекта и освобождать те, которые помечены copy или retain . Тогда в -dealloc у вас было бы что-то вроде [self releaseProperties] . Я также делал это, но я также не рекомендую этого делать, поскольку это может вызвать незначительные проблемы, которые могут привести к необъяснимым сбоям, если вы не будете осторожны.

Ответ №3:

Чтобы на самом деле добавить переменную-член в objective-c, вам не нужно ничего этого делать.

Что вы делаете в этих 3 шагах, так это:

  1. Объявляйте свойства для переменной-члена. (В вашем случае вы указываете, что хотите, чтобы установщик свойств «сохранял» объект, для которого он устанавливает вашу переменную-член)

  2. Объявите средства получения и установки свойств по умолчанию для вашего свойства.

  3. Освободите объект, сохраняемый вашим свойством.

ЕСЛИ вы хотели объявить только переменную-член, все, что вам нужно было сделать, это объявить ее внутри вашего класса:

 @interface SomeClassObject : NSObject {
   int someMemberVariable;
}
@end
  

Ответ №4:

Это 3 раза, когда пишется то, что по сути является одним и тем же

Нет, это не так.

 @property (retain) aMember;
  

В приведенной выше строке объявляется свойство, чтобы компилятор знал, что можно отправлять сообщения -aMember и -setAMember: объектам вашего класса. Это также сообщает компилятору (и разработчикам), что свойство является сохраняемым свойством (т. Е. объект, для которого вы задаете свойство, будет сохранен), что он доступен для чтения / записи и что он атомарный.

 @synthesize aMember;
  

Приведенная выше строка сообщает компилятору, что он должен автоматически сгенерировать методы setter и getter для объявленного свойства. Вы можете оставить это, но тогда вам придется написать свой собственный установщик и получатель.

 [aMember release]; // in dealloc
  

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

Каждая из этих строк выполняет разные действия. Таким образом, вы не делаете одно и то же три раза.