Я вижу ситуацию, когда NSFetchRequest возвращает различное количество объектов в зависимости от того, выполняется ли он напрямую через NSManagedObjectContext или как часть построения NSFetchedResultsController.
Пример кода:
- (void)setupResultsController {
NSError *error = nil;
NSManagedObjectContext *ctx = [[DataManager sharedInstance] mainObjectContext];
// Create a fetch request and execute it directly
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [Song entityInManagedObjectContext:ctx];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"section" ascending:YES];
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor, nameDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *debugResults = [ctx executeFetchRequest:fetchRequest error:&error];
NSLog(@"Count from context fetch: %lu", (unsigned long)debugResults.count);
// Use the request to populate a NSFetchedResultsController
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:ctx
sectionNameKeyPath:@"section"
cacheName:@"Detail"];
[aFetchedResultsController performFetch:&error];
NSLog(@"Count from results controller fetch: %lu", (unsigned long)[[aFetchedResultsController fetchedObjects] count]);
_songResultsController = aFetchedResultsController;
}
Выполнение вышеуказанных результатов в сообщениях журнала:
2020-01-10 11: 05: 07.892772-0500 asb7 [12985: 105052] Подсчет из выборки из контекста: 10
2020-01-10 11: 05: 07.893259-0500 asb7 [12985: 105052] Подсчет из выборки контроллера результатов: 9
Разница между двумя выборками заключается в том, что NSFetchedResultsController отсутствует последний добавленный объект. Крайняя странность заключается в том, что после запуска приложения некоторое, казалось бы, случайное число раз, счетчики начинают совпадать, и новый объект извлекается.
Редактировать:
Результаты становятся согласованными, если я передаю nil
в качестве имени кэша или если я удаляю дескриптор второй сортировки. Очевидно, что они вызывают нежелательные изменения поведения, но могут быть подсказками.
Кажется, что NSFetchedResultsController видит устаревший кеш как действительный. Изменение дескриптора сортировки делает недействительным кэш, однако обновление файла постоянного хранилища должно сделать его недействительным, но, по-видимому, в этом случае это не так.
После еще нескольких экспериментов у меня есть объяснение ... если не решение Добавление новых объектов не меняет дату изменения моего файла .sqlite. Он обновляет .sqlite-shm и .sqlite-wal, но я предполагаю, что они не учитываются при оценке использования кэша. Использование touch
из терминальной сессии устраняет проблему go для следующего запуска.
(Xcode 10.1, macOS 10.13.6, цель развертывания 10.3, iOS 12.1 симулятор и устройство 10.3.2)
Другое редактирование:
Я загрузил заархивированный каталог проекта, который демонстрирует проблему в https://github.com/PhilKMills/CacheTest
Что Я получаю это: первый запуск, 3 записи для обеих выборок; второй запуск, 6 и 3. Я считаю вполне вероятным, что это зависит от моих конкретных версий программного обеспечения, но в настоящий момент я не в состоянии выполнить обновление. Результаты других людей были бы наиболее интересны.
Примечание: без назначения делегата FR C проблема не появляется.