Базовые данные - странное исключение при объединении контекста из другого потока - PullRequest
0 голосов
/ 21 сентября 2011

У меня есть фоновая задача, которая извлекает большой объем данных, сохраняет их в контексте основных данных, и этот контекст объединяется с контекстом в главном потоке.

У меня есть таблица, в которой эти данные перечислены через NSFetchedResultsController.

Иногда (но очень редко) я получаю странную ошибку в этой области кода:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    /* standard uitableview cell stuff */

    PSCourse *course = [_fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = course.name; // <--- EXCEPTION HERE

    return cell;
}

Я получаю остановку на линии, указанной выше (через точку останова исключения obj-c).

Если я нажимаю продолжить в отладчике, я получаю эту непонятную ошибку:

Утверждение не удалось: (_Unwind_SjLj_Resume () не может вернуться), функция _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, строка 326.

Я не уверен, почему приложение зависало в строке выше, но, возможно, рассматриваемый объект был удален во время рендеринга этого объекта в табличном представлении. Если это так, что мне делать? Должен ли я проглотить ошибку? Стоит ли как-то проверять состояние контроллера извлеченных результатов?

Заранее спасибо.

1 Ответ

0 голосов
/ 21 сентября 2011

Можете ли вы удалить остановку исключений и посмотреть, видите ли вы настоящее исключение?

Загадочная ошибка выглядит так, как будто в системе исключений происходит сбой.«Unwind» = разматывать стек, общий метод передачи выполнения обработчикам исключений;"sjlc" = setjump / longjump, механизм C для разматывания стека;"resume" = потому что отладчик остановил его на полпути?

В любом случае, если изменение (или удаление) объекта в фоновом потоке является причиной вашей проблемы, возможно, вы могли бы решить ее, заблокировав постоянное хранилищекоординатор в cellForRowAtIndexPath.Не нужно ждать завершения всей фоновой задачи.Поскольку вы явно не блокируете фоновую задачу (я полагаю), Core Data будет использовать более или менее разумную стратегию для блокировки, возможно, получая и снимая блокировку с каждой операцией.Таким образом, вашему пользовательскому интерфейсу нужно только ждать одну операцию (возможно, одну небольшую серию операций).

Это может все еще реально ухудшить производительность, но не мешает попробовать это.Даже если это делает производительность неприемлемой, если это решает вашу проблему, вы можете принять это как подтверждение того, что, по крайней мере, вы угадали причину.

...