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