Требуется ли освобождение памяти для свойств Objective-c 2.0?
Что-то, что меня интересует о свойствах некоторое время. Когда вы используете свойства, нужно ли переопределить сообщение о выпуске, чтобы убедиться, что свойства являются выпущенными свойствами?
т.е. достаточен ли следующий (вымышленный) пример?
@interface MyList : NSObject {
NSString* operation;
NSString* link;
}
@property (retain) NSString* operation;
@property (retain) NSString* link;
@end
@implementation MyList
@synthesize operation,link;
@end
6 ответов
Вы должны всегда освобождать вспомогательные переменные в dealloc:
- (void) dealloc {
[operation release];
[link release];
[super dealloc];
}
По-другому:
- (void) dealloc {
self.operation = nil;
self.link = nil;
[super dealloc];
}
Это не предпочтительный способ освобождения объектов, но в случае, если вы используете синтезированные переменные поддержки, это единственный способ сделать это.
ПРИМЕЧАНИЕ: чтобы понять, почему это работает, давайте посмотрим на синтезированную реализацию метода установки для свойства link и что происходит, когда оно установлено в nil:
- (void) setLink:(MyClass *) value {
[value retain]; // calls [nil retain], which does nothing
[link release]; // releases the backing variable (ivar)
link = value; // sets the backing variable (ivar) to nil
}
Таким образом, чистый эффект заключается в том, что он выпустит ивар.
В не-GC приложениях, да. Обычно назначают ноль вместо выпуска иваров. Мой лучший опыт заключается в том, чтобы выпустить ivars, инициализированный с помощью init, и назначить nil для свойств с режимом сохранения и копирования.
В вашем случае я бы назначил ноль
- (void) dealloc {
self.operation = nil;
self.link = nil;
[super dealloc];
}
Лучший способ сделать это:
- (void)dealloc {
[operation release], operation = nil;
[link release], link = nil;
[super dealloc];
}
Действительно, было бы удобнее использовать сгенерированные методы установки
self.operation = nil;
но это осуждается. Вы не всегда знаете, в каком потоке объект освобожден. Таким образом, использование средства доступа может вызвать проблемы, вызывая уведомления KVO.
Уловка здесь в том, что вам нужно адаптировать свой Deloc для соответствия политике управления объектами, определенной в вашем @property. Например, не выпускайте iVar, поддерживающий (назначайте) свойство.
Нет, вы отменяете -dealloc
метод. И да, если вы не освободите свои свойства (или, скорее, резервные ivars), вы утечете. Так что в вашем @implementation вы должны иметь что-то вроде
- (void)dealloc {
[operation release];
[link release];
[super dealloc];
}
Синтезирование свойства создает только методы получения и установки, и поэтому не освобождает ивар, когда объект освобождается. Вы должны выпустить ивар самостоятельно.
В pre-ARC всякий раз, когда вы видите new, alloc, retain и copy, будь то экземпляр var или свойство, которое вы должны освободить. В ARC, когда у вас есть сильная переменная, вы должны установить ее на ноль. В любом случае вы должны переопределить dealloc().