Предотвращение EXC_BAD_ACCESS при использовании шаблона делегата

Контроллера представления, и это создает объект "загрузчика", который имеет ссылку на контроллер представления (как делегат). Загрузчик отзывает контроллер представления, если он успешно загружает объект. Это хорошо работает, пока Вы остаетесь на представлении, но если Вы перешли далеко, прежде чем загрузка завершена, я добираюсь EXC_BAD_ACCESS. Я понимаю, почему это происходит, но является там каким-либо способом проверить, выделяется ли объект все еще? Я пытался протестировать использование delegate != nil, и [delegate respondsToSelector:], но это дросселирует.

if (!self.delegate || ![self.delegate respondsToSelector:@selector(downloadComplete:)]) {
  // delegate is gone, go away quietly
        [self autorelease];
        return;
    }
else {
  // delegate is still around
  [self.delegate downloadComplete:result];
}

Я знаю, что мог,

a) имейте объекты загрузчика, сохраняют контроллер представления

b) сохраните массив загрузчиков в контроллере представления и установите их значения делегата к нолю, когда я буду освобождать контроллер представления.

Но интересно, существует ли более легкий путь, где я просто тестирую, если адрес делегата содержит доступный объект?

18
задан Kenny Winker 21 April 2010 в 03:44
поделиться

2 ответа

Нет, вы не можете (полезно) " проверить, содержит ли адрес действительный объект ". Даже если вы смогли порыться внутри системы распределения памяти и определить, что ваш адрес указывает на действительный объект, это не обязательно будет означать, что это тот же объект , на который вы ранее ссылались. : объект мог быть освобожден, а другой объект был создан по тому же адресу памяти.

Сохранение делегата - обычный способ решить эту проблему. Ваш вариант (b) нарушает инкапсуляцию объекта и может иметь проблемы с поточной безопасностью.

10
ответ дан 30 November 2019 в 07:08
поделиться

Я бы просто написал

SEL slc = @selector(theSlc);
if ([delegate respondsToSelector:slc]) {
    [delegate performSelector:slc];
}

Если объект действителен, метод будет вызван, в противном случае - нет. Вам не нужно проверять

self.delegate != nil
1
ответ дан 30 November 2019 в 07:08
поделиться