#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 строки, под прикрытием вашего.
-
Ваше объявление @property сообщает objective-c некоторые важные атрибуты (атомарный, неатомный, сохранение, копирование и т.д.) О том, как обращаться с вашим свойством, когда оно устанавливается пользователями вашего класса. Когда вы думаете об этом, эти атрибуты (без написания вами какого-либо кода) помогают вам создавать потокобезопасный код, обрабатывать ссылки на объекты, чтобы вам не приходилось беспокоиться о том, что они исчезнут у вас, или копировать значения, чтобы у вас была собственная копия объекта. Свойство @ также важно, поскольку оно объявлено в вашем заголовочном файле (обычно). Это дает другим разработчикам представление о свойствах вашего класса и несколько небольших подсказок относительно того, как объекты, которые они передают в эти свойства, будут обрабатываться в течение его жизненного цикла.
-
@synthesize также выполняет довольно большую работу, создавая средства получения и настройки для этого свойства, которые также обрабатывают все виды управления памятью для вас. Вам не нужно беспокоиться о том, чтобы удалить старые ссылки и правильно ссылаться на новый объект. Для меня это само по себе отличная функция, особенно когда вы новичок в objective-c и легко забыть разобраться с управлением памятью на каждом шагу. @synthesize просто делает это за вас, и вам не нужно писать весь код get и set самостоятельно.
-
Вызов 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 все еще работает над этим. Но на данный момент вам действительно нужно явно синтезировать.
Несколько других замечаний:
-
Если вы используете сборку мусора, вам не нужно внедрять
-dealloc
: просто убедитесь, что выполняете любую очистку в последнюю минуту в-finalize
(например, отменяете регистрацию уведомлений). -
Вы также могли бы избежать этого
-dealloc
бита, заключив переменную вашего экземпляра в класс C , который выполняет управление памятью во время построения и уничтожения:@property prop_wrapper<Blorg> blorg;
сработало бы. Затем, когда ваш объект будет уничтожен,~prop_wrapper()
будет вызван для вашего объекта. Я сделал это, и это работает, но я не рекомендую этого делать, поскольку это плохо сочетается с KVO и KVC. -
Вы могли бы перебирать свойства объекта и освобождать те, которые помечены
copy
илиretain
. Тогда в-dealloc
у вас было бы что-то вроде[self releaseProperties]
. Я также делал это, но я также не рекомендую этого делать, поскольку это может вызвать незначительные проблемы, которые могут привести к необъяснимым сбоям, если вы не будете осторожны.
Ответ №3:
Чтобы на самом деле добавить переменную-член в objective-c, вам не нужно ничего этого делать.
Что вы делаете в этих 3 шагах, так это:
-
Объявляйте свойства для переменной-члена. (В вашем случае вы указываете, что хотите, чтобы установщик свойств «сохранял» объект, для которого он устанавливает вашу переменную-член)
-
Объявите средства получения и установки свойств по умолчанию для вашего свойства.
-
Освободите объект, сохраняемый вашим свойством.
ЕСЛИ вы хотели объявить только переменную-член, все, что вам нужно было сделать, это объявить ее внутри вашего класса:
@interface SomeClassObject : NSObject {
int someMemberVariable;
}
@end
Ответ №4:
Это 3 раза, когда пишется то, что по сути является одним и тем же
Нет, это не так.
@property (retain) aMember;
В приведенной выше строке объявляется свойство, чтобы компилятор знал, что можно отправлять сообщения -aMember
и -setAMember:
объектам вашего класса. Это также сообщает компилятору (и разработчикам), что свойство является сохраняемым свойством (т. Е. объект, для которого вы задаете свойство, будет сохранен), что он доступен для чтения / записи и что он атомарный.
@synthesize aMember;
Приведенная выше строка сообщает компилятору, что он должен автоматически сгенерировать методы setter и getter для объявленного свойства. Вы можете оставить это, но тогда вам придется написать свой собственный установщик и получатель.
[aMember release]; // in dealloc
Можно ли сообщить среде выполнения, что при освобождении объекта ему больше не нужно содержать ссылку на эту переменную экземпляра. Это необходимо, потому что, когда вы используете подсчет ссылок, а не сборку мусора, среда выполнения автоматически не очищает ненужные объекты.
Каждая из этих строк выполняет разные действия. Таким образом, вы не делаете одно и то же три раза.