О том, каким образом следует реализовывать в коде retain property знать нужно. Это необходимо не только для лучшего понимания работы директивы @synthesize, но и в случае, если нужно будет реализовать не стандартное поведение в сеттере (мутаторе).
Директива @synthesize value; сгенерирует следующий код:
- (void)setValue: (id)newValue
{
if (value != newValue)
{
[value release];
value = newValue;
[value retain];
}
}
Более внимательное изучение этого кода позволит нам заметить одно его интересное свойство: для освобождения памяти в методе dealloc нам не обязательно посылать объекту release, можно ограничиться конструкцией self.value = nil;. В этом случае, как видно из кода, сначала освободится старое значение, потом переменная “занулится”, а сообщение retain не будет иметь эффекта для переменной nil. Таким образом, решится сразу 2 задачи: память будет освобождена, а переменная станет nil, что может позволить избежать некоторых нежелательных падений приложения.
При обращении к переменной value следует помнить, что вызов вида
self.value = …
Вызывает функцию setValue и увеличивает счетчик объекта на 1.
А код вида
value = …
Работает напрямую с переменной, минуя вызов setValuе. Соответственно, счетчик объекта дополнительно не увеличивается. Таким образом можно выделить следующие правильные способы работы с retain-property:
- Создание временной переменной, alloc/init (= retained), установка свойства, release.
UIView *tempOverlay = [[UIView alloc] initWithFrame:CGRectMake(160.0f, 70.0f, 150.0f, 310.0f)];
self.overlay = tempOverlay;
[tempOverlay release];
- Работа “напрямую”.
value= [[UIView alloc] initWithFrame:CGRectMake(160.0f, 70.0f, 150.0f, 310.0f)];
Ну и конечно, не стоит забывать об освобождении (release) всего ненужного в методе dealloc.
Полезная статья? Их будет больше, если вы поддержите меня!
Архив комментариев
1 комментарий из прежней версии блога. Архив закрыт для новых ответов.
Большое спасибо! Теперь у меня в голове все встало на свои места. :)