Я изменил свое приложение из одного контекста с хранилищем sqlite, управляемым в делегате приложения, на UIManagedDocument (как шаблон Xcode по умолчанию с активированными Core Data).
Теперь у меня странное поведение при попытке выбрать объекты, созданные с момента запуска текущего приложения, после того, как я закрыл (задал фон) и снова открыл приложение.
Есть 2 объекта: папка и элемент.
Папка с элементом - это отношение ко многим.
Предикат моего fetchedResultsController для отображения элементов в текущей папке выглядит так:
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(folder == %@)", self.currentFolder]];
Это все еще хорошо работает в одной ситуации:
- Я создаю новую папку, добавляю в нее некоторые элементы
- Затем закройте (фон) и снова откройте приложение
- Выберите эту папку для отображения в TableView
Тогда выборка возвращает 0 результатов.
Как только я убиваю приложение и снова открываю его, элементы папки снова отображаются (и fetchRequests возвращает правильное количество элементов).
Я провел дополнительное тестирование внутри viewDidAppear с некоторыми ручными запросами fetch без fetchedResultsController.
И я действительно не понимаю, как это может произойти.
Оба запроса fetch в основном одинаковы (и идентичны запросам fetchedResultController),
но первый не имеет предиката, а затем проверяет в цикле for, является ли папка элемента currentFolder viewController.
Насколько я понимаю, это должно привести к точно такому же поведению, но в то время как предикат дает сбой после фоновой обработки,
выборка всех элементов + тестирование в цикле for работает нормально все время.
// Returns fetchResult.count = 0 for new created folders after backgrounding the app
[fetchRequest1 setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context]];
[fetchRequest1 setPredicate:[NSPredicate predicateWithFormat:@"(folder == %@)", self.currentFolder]];
NSArray *fetchResult1 = [self.context executeFetchRequest:fetchRequest1 error:nil];
// This time get all items in the context withour predicate
[fetchRequest2 setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context]];
[fetchRequest2 setPredicate:nil];
NSArray *fetchResult2 = [self.context executeFetchRequest:fetchRequest1 error:nil];
// Filter to get only the items in the current folder
NSMutableArray *filteredFetchResults2 = [NSMutableArray mutableArrayWithCapacity:0];
for (Item *item in fetchResult2) {
if (item.folder == self.currentFolder) [filteredFetchResults2 addObject:item];
}
// filteredFetchResults2 holds the correct items even after backgrounding. Why?!?
Как это могло быть?