0

Здесь я нашел много вопросов о методе делегатов и пробовал много вариантов, но все же имеет исключение BAD_ACCESS.Делегат с асинхронным обратным вызовом

Мое приложение получает данные из сети асинхронно через NSUrlConnection. Я использую специальный объект обмена данными с делегатом в VC.

С опцией отладки NSZombies я получаю сообщение: [MyViewController tableView: titleForHeaderInSection:]: сообщение отправлено на освобожденный экземпляр 0x79698490.

VC:

@property DataManager *man; 

- (void)viewDidLoad { 
... 
man = [[DataManager alloc] initWithDelegate:self]; 
... 
} 

- (void) myDelegateSelector { 
// DataManager call this method when data is ready 
... save data ... 
_tableView reloadSections ... // refresh content 
} 

DataManager:

@property (weak, nonatomic) id <DataManagerDelegate> delegate; 

- (id) initWithDelegate:(id <DataManagerDelegate>)delegate { 
... 
_delegate = delegate; 
} 

- (void) receiveSomeData { 
... 
dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
     ... receive data work in global queue 
     if (_delegate) 
      // going back to the main queue cause need to change on screen data 
      dispatch_async(dispatch_get_main_queue(), ^{ 
        if ([_delegate respondsToSelector:@selector(myDelegateSelector:)]) 
         [_delegate myDelegateSelector]; 
      }); 
    }); 
} 
+0

это означает, что ваш MyViewController в настоящее время освобождаться, пока вы пытаетесь заставить его сделать что-то. кто создает/управляет вашим MyViewController? В вашем коде не отображается какой контроллер. – mitrenegade

+0

Да, я знаю. VC, созданный родительским контроллером. Когда пользователь быстро нажимает кнопку «назад», данные все еще загружаются, и иногда я получаю исключение. –

ответ

0

Проблема успешно решена.

Решение:

код VC:

- (void) dealloc 
{ 
    _tableview.datasource = nil; 
} 
0

в этом случае, вы всегда должны удалить делегат в методе dealloc. Для вашего контроллера:

-(void)dealloc { 
    man.delegate = nil; 
} 

Вы уже проверили, если (_delegate). Не устанавливая его на ноль, когда ваш VC быстро закрывается, _delegate освобождается, но не равен нулю.

+0

_delegate - слабая ссылка, почему это не ноль, когда VC освобожден? –

+0

Я не совсем уверен в механизме, но это объясняется здесь. http://stackoverflow.com/questions/20653841/why-do-we-set-delegate-to-nil-at-dealloc-if-the-object-is-going-to-be-destroyed И если вы добавите контрольные точки , вы видите, что делегат освобожден, но не равен нулю, и является своего рода указателем памяти, который является недопустимым, но существует. если делегат не равен нулю, он фактически попытается ссылаться на делегат и заставить его выполнить вызов, что приведет к сбою. – mitrenegade

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