Я устанавливаю свойства в nil в dealloc при использовании ARC?


Я пытаюсь изучить автоматический подсчет ссылок в iOS 5. Теперь первая часть этого вопроса должна быть легкой:

  1. правильно ли, что я делаю не нужно написать явное инструкции release-property в моем dealloc при использовании ARC? В других слова, это правда, что следующее делает не нужен явный dealloc?

    @interface MyClass : NSObject
    @property (strong, nonatomic) NSObject* myProperty;
    @end
    
    @implementation MyClass
    @synthesize myProperty;
    @end
    
  2. мой следующий и более важный вопрос исходит из строки переход к заметкам о выпуске ARC документ:

    вам не нужно (действительно не может) освобождать переменные экземпляра, но вам может потребоваться вызвать [self setDelegate:nil] для системных классов и другого кода, который не компилируется с помощью ARC.

    возникает вопрос: Как узнать, какие системные классы не компилируются с помощью ARC? Когда я должен создавать свой собственный dealloc и явно устанавливать сильно сохраняющие свойства на ноль? Должен Ли Я предположим, что все классы NS и UI framework, используемые в свойствах, требуют явного освобождения?

существует множество информации о SO и в других местах о практике освобождения резервного ivar свойства при использовании ручного отслеживания ссылок, но относительно мало об этом при использовании ARC.

2 123

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, тогда, возможно, вам пора снова проверить своих сеттеров.