Версии (1): лучший.У каждого из остальных есть атрибуты, которые могут быть вредными.
Версия (2): Обычно рекомендуется не использовать средства доступа в dealloc (или init).Причиной этого является то, что объект находится в процессе разрушения (или создания) и находится в противоречивом состоянии.Это особенно верно, если вы пишете библиотеку, где кто-то другой может позже переопределить метод доступа, не подозревая, что он может быть вызван, когда объект находится в несовместимом состоянии.(Конечно, даже Apple иногда нарушает это правило -[UIView initWithFrame:]
, вызывает -[UIView setFrame:]
, если аргумент не является CGRectZero
, что может быть полезно для отладки.
Version (3); Установка ivar на nil
служитбесполезная цель, на самом деле это может маскировать ошибку и затруднить отладку more . Чтобы понять, почему это так, рассмотрим следующий фрагмент кода, предположим, что myObject имеет версию (3) dealloc
.
FastMovingTrain* train = [[FastMoving alloc] init];
MyObject* myObject = [[MyObject alloc] init];
myObject.foo = train;
[train release];
// my myObject.foo is the only thing retaining train
...
....
[myObject release];
// Because of version (3) dealloc if myObject
// points to the dealloced memory this line
// will silently fail...
[myObject.foo applyBrakes];
Интересно, что этот код предоставляет возможность продемонстрировать, когда установка переменной nil
после того, как release
имеет смысл. Код можно сделать более устойчивым, изменив его следующим образом.
FastMovingTrain* train = [[FastMoving alloc] init];
MyObject* myObject = [[MyObject alloc] init];
myObject.foo = train;
[train release];
// my myObject.foo is the only thing retaining train
...
....
[myObject release];
myObject = nil;
// This assertion will fail.
NSAssert(myObject, @"myObject must not be nil");
[myObject.foo applyBrakes];
Просто мои 0,02 доллара.