Требуется ли освобождение памяти для свойств 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().

Другие вопросы по тегам