Я устанавливаю свойства в nil в dealloc при использовании ARC?
Я пытаюсь изучить автоматический подсчет ссылок в iOS 5. Теперь первая часть этого вопроса должна быть легкой:
-
правильно ли, что я делаю не нужно написать явное инструкции release-property в моем dealloc при использовании ARC? В других слова, это правда, что следующее делает не нужен явный dealloc?
@interface MyClass : NSObject @property (strong, nonatomic) NSObject* myProperty; @end @implementation MyClass @synthesize myProperty; @end
-
мой следующий и более важный вопрос исходит из строки переход к заметкам о выпуске ARC документ:
вам не нужно (действительно не может) освобождать переменные экземпляра, но вам может потребоваться вызвать [self setDelegate:nil] для системных классов и другого кода, который не компилируется с помощью ARC.
возникает вопрос: Как узнать, какие системные классы не компилируются с помощью ARC? Когда я должен создавать свой собственный dealloc и явно устанавливать сильно сохраняющие свойства на ноль? Должен Ли Я предположим, что все классы NS и UI framework, используемые в свойствах, требуют явного освобождения?
существует множество информации о SO и в других местах о практике освобождения резервного ivar свойства при использовании ручного отслеживания ссылок, но относительно мало об этом при использовании ARC.
2 ответа:
короткий ответ:: нет, вы не должны обнулять свойства в
dealloc
под дуги.ответ: вы никогда не должны обнулять свойства в
dealloc
, даже в ручном управлении памятью.в MRR, вы должны освободить ваш Ивар. Nilling out properties означает вызов сеттеров, которые могут вызывать код, который он не должен касаться в
dealloc
(например, если ваш класс, или подкласс, переопределяющий сеттер). Точно так же это может триггер уведомления KVO. Освобождение ivar вместо этого позволяет избежать этих нежелательных поведений.в ARC система автоматически выпускает любые ivars для вас, поэтому, если это все, что вы делаете, вам даже не нужно реализовывать
dealloc
. Однако, если у вас есть какие-либо не объектные ивары, которые нуждаются в специальной обработке (например, выделенные буферы, которые вам нужноfree()
) вы все еще должны иметь дело с теми, вdealloc
.кроме того, если вы установили себе в качестве делегата каких-либо объектов, вы следует отменить установку этого отношения в
dealloc
(Это о вызове[obj setDelegate:nil]
). Примечание об этом в классах, которые не компилируются с помощью ARC, является кивком в сторону слабых свойств. Если класс явно отмечает егоdelegate
имущество в видеweak
тогда вам не нужно этого делать, потому что природа слабых свойств означает, что она будет уничтожена для вас. Однако, если свойство помеченоassign
тогда вы должны обнулить его в своемdealloc
, в противном случае класс остается с висячим указателем и, скорее всего, произойдет сбой, если он попытается отправить сообщение своему делегату. Обратите внимание, что это относится только к нераспределенным отношениям, таким как делегаты.
просто чтобы дать противоположный ответ...
короткий ответ:: нет, вы не пропустит вне автоматически синтезированные объекты в
dealloc
под дуги. И вы не должны использовать сеттер для тех, ктоinit
.ответ вы должны nil out пользовательские синтезированные свойства в
dealloc
, даже под дуги. И вы должны использовать сеттер для тех, ктоinit
.дело в том, что ваш пользовательский синтезированный свойства должны быть безопасными и симметричными относительно обнуления.
возможный сеттер для таймера:
-(void)setTimer:(NSTimer *)timer { if (timer == _timer) return; [timer retain]; [_timer invalidate]; [_timer release]; _timer = timer; [_timer fire]; }
возможный сеттер для scrollview, tableview, webview, textfield, ...:
-(void)setScrollView:(UIScrollView *)scrollView { if (scrollView == _scrollView) return; [scrollView retain]; [_scrollView setDelegate:nil]; [_scrollView release]; _scrollView = scrollView; [_scrollView setDelegate:self]; }
возможный сеттер для свойства KVO:
-(void)setButton:(UIButton *)button { if (button == _button) return; [button retain]; [_button removeObserver:self forKeyPath:@"tintColor"]; [_button release]; _button = button; [_button addObserver:self forKeyPath:@"tintColor" options:(NSKeyValueObservingOptions)0 context:NULL]; }
тогда вам не придется дублировать код
dealloc
,didReceiveMemoryWarning
,viewDidUnload
, ... и ваша собственность может быть безопасно обнародована. Если вы беспокоились о нулевых свойств вdealloc
, тогда, возможно, вам пора снова проверить своих сеттеров.