0

У меня проблема с ARC. После нескольких часов отладки я сдался и решил проверить здесь.ARC не освобождает переменную экземпляра

В основном у меня есть MainViewController, который создает экземпляр PreviewsView.

В PreviewsView у меня есть делегат и DataSource свойства:

@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDataSource> dataSource; 
@property (nonatomic, unsafe_unretained) IBOutlet id<PreviewsDelegate> delegate; 

Я создаю экземпляр PreviewsView в MainViewController, установите self в delegate и dataSource, добавить его для просмотра и сохранения в качестве переменной экземпляра:

- (void)addPreviews { 
    previewsView = [[PreviewsView alloc] initWithFrame:CGRectMake(0, 75, 1024, 480)]; 
    previewsView.dataSource = self; 
    previewsView.delegate = self; 
    [self.view addSubview:previewsView]; 
} 

Тогда, когда я удаляю MainViewController от контроллера навигации ACR освобождает, НО previewsView все еще существует (W HY ???) и фактически запускает метод, который вызывает [self.delegate doSomeStuff]. Поскольку MainViewController уже освобождает - он выбрасывает EXC_BAD_ACCESS.

Так в основном:

  • Инстанция MainViewController владеет экземпляром PreviewsView (previewsView)
  • Инстанция MainViewController назначен delegate и dataSource в PreviewsView
  • После открепления экземпляра MainViewController, previewsView все еще жив и Бег.

Любые идеи, почему? Спасибо.

+1

Преднамеренно ли вы создаете представление с именем 'previewsView' (в методе' addPreviews'), но добавляете совершенно другое подвью ('previewsCaroucel')? – omz

+0

извините, это связано с переименованием переменных перед публикацией здесь – OgreSwamp

ответ

1

unsafe_unretained не ноль ivar. __weak делает.

Поддерживает ли элемент MainViewController previewsView? В viewDidUnload или после того, как вы закончили с previewsView, установите его на ноль, то есть: previewsView = nil.

Как правило, все IBOutlets или subviews, хранящиеся как ivars, должны быть __weak. Если вам не нужен PreviewsView после добавления его в качестве подзаголовка, вы можете удалить ivar.

Надеюсь, это поможет!

+0

AFAIK 'weak' недоступен в iOS 4.x, так что это не решение для меня. – OgreSwamp

+1

По этой причине вы должны явно указать свой член или не сохранять его. –

+0

Как нуль в этом случае поможет? Nil не будет выпускать previewsView, previewsView по-прежнему будет иметь ссылку на выпущенный MainViewController. – OgreSwamp

2

вам нужно установить своих делегатов на нуль, прежде чем отпустить MainViewController так previewsView.delegate = nil; previewsView.dataSource = nil;

Предпочтительнее называют этот код в методе dealloc вами MainViewController -> вы можете использовать его также с ARC, как это

- (void) dealloc 
{ 
    previewsView.dataSource = nil; 
    previewsView.delegate = nil; 
    [super dealloc]; 
} 

Вы должны иметь в виду, что протоколы принимает! ваш экземпляр previewsView все еще «живой» (уведомления работают одинаково) и попытайтесь отправить сообщения в ваш экземпляр, будь он мертв или жив. Поэтому, когда MainViewController обновляется, также отображается previewsView, но делегаты все еще «живы».Поэтому вам нужно отменить их, установив их на nil;)

Смежные вопросы