Чтобы я не похоронил светодиод, я собираюсь открыть с моим основным вопросом: почему мой массив FetchedObjects NSFetchedResultsController обычно является однородным, но в редких случаях содержит __NSCFString
среди управляемых объектов, которые он должен содержать?Почему массив NSFetchedResultsController's fetchedObjects не всегда однородный
У меня есть приложение, которое работает в течение долгого времени. Основной вид - это табличное представление, которое содержит список видео, поддерживаемых основными объектами, управляемыми данными. Контроллер табличные использует NSFetchedResultsController
сконфигурированные с довольно обычным NSFetchRequest
:
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:[ABCVideo entityName]];
NSString *sectionKeyPath = nil;
request.fetchBatchSize = 20;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:ABCVideoAttributes.recordingDate ascending:NO];
sectionKeyPath = @"sectionIdentifier";
request.sortDescriptors = @[sort];
request.predicate = [NSPredicate predicateWithFormat:@"owner = %@ and %K = %@", person, ABCVideoAttributes.serverDeleted, @(NO)];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:sectionKeyPath cacheName:kABCMyVideosTableViewControllerCacheKey];
Поскольку это видео может быть загружено в облако, этот вид таблицы контроллер получает случайные уведомления обновить прогресс бары в представлении ячейки таблицы, соответствующая видео которые в настоящее время загружаются. Внутри этого обратного вызова мы получаем массив fetchedObjects
, чтобы найти видео, соответствующее уведомлению, так что правильная ячейка представления таблицы может обновить индикатор выполнения.
Все это работает. 99,9% времени, он работает каждый раз </RonBurgundy>
.
Но я заметил в наших отчетах о сбоях HockeyApp, что редкий, редкий случай, когда я получал SIGABRT, что происходит, когда мой обработчик уведомлений пытается получить filteredArrayUsingPredicate
от fetchedObjects
:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x136f24480> valueForUndefinedKey:]: this class is not key value coding-compliant for the key guid.'
Недавно мне удалось найти случай, когда я мог бы иногда воспроизвести этот крах, и после большого количества экспериментов я обнаружил, что в массиве fetchedObjects
иногда содержалось то, что не было ABCVideo
: вместо этого один слот в массиве был занят __NSCFString
экземпляр. Это было довольно удивительно, учитывая, что NSFetchRequestResultType
имеет значение NSManagedObjectResultType
, а строка не является управляемым объектом.
Так что мне осталось интересно: это ошибка ядра? Или мой массив содержит указатель, который ранее указывал на экземпляр ABCVideo
, который был освобожден, и что место в куче впоследствии было взято экземпляром __NSCFString
? Если это последний, то как это могло произойти? Я использую ARC, поэтому трудно понять, как одно из этих видео может быть освобождено.
Я подозреваю, что ошибка Core Data. В iOS9 появилось несколько ошибок, особенно с NSFetchedResultsControllers, и это может быть другое. – Avi
Сам массив должен сохранять свои объекты, поэтому, если вы каким-то образом не освобождаете слишком много, их не следует освобождать. Кроме того, с ARC это почти наверняка не так. Может быть ошибкой ARC или ошибкой Core Data. Можете ли вы исключить, что это связано с кэшированием с помощью 'NSFetchedResultsController'? Отключить кеширование и воспроизведение? – SmokeDispenser
Поскольку вы можете воспроизвести его, может быть полезно обнаружить, когда это произойдет, и проверить содержимое строки. Я не знаю, почему строка есть, но ее содержимое может указывать на причину. –