У меня есть базовая модель данных с тремя объектами:Person
, Group
, Photo
со следующими отношениями между ними:
- Человек ‹‹-----------> Группа (отношение один ко многим)
- Человек ‹-------------> Фото (один к одному)
Когда я выполняю выборку, используя NSFetchedResultsController
в UITableView
, я хочу сгруппировать в разделы объекты Person
, используя атрибут name
сущности Group
.
Для этого я использую sectionNameKeyPath:@"group.name"
.
Проблема в том, что когда я использую атрибут из отношения Group
, NSFetchedResultsController
извлекает все заранее небольшими партиями по 20 (у меня setFetchBatchSize: 20
), а не извлекает партии, пока я прокручиваю tableView
.
Если я использую атрибут объекта Person
(например, sectionNameKeyPath:@"name"
) для создания разделов, все работает нормально: NSFetchResultsController
загружает небольшие пакеты из 20 объектов при прокрутке.
Код, который я использую для создания экземпляра NSFetchedResultsController:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:[Person description]
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Specify how the fetched objects should be sorted
NSSortDescriptor *groupSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"group.name"
ascending:YES];
NSSortDescriptor *personSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthName"
ascending:YES
selector:@selector(localizedStandardCompare:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:groupSortDescriptor, personSortDescriptor, nil]];
[fetchRequest setRelationshipKeyPathsForPrefetching:@[@"group", @"photo"]];
[fetchRequest setFetchBatchSize:20];
NSError *error = nil;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(@"Error Fetching: %@", error);
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"group.name" cacheName:@"masterCache"];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
Вот что я получаю в инструментах, если создаю разделы на основе "group.name"
без какого-либо взаимодействия с пользовательским интерфейсом приложения:
И это то, что я получаю (с небольшой прокруткой в UITableView), если sectionNameKeyPath равен нулю:
Пожалуйста, может ли кто-нибудь помочь мне в этом вопросе?
ИЗМЕНИТЬ 1:
Кажется, что я получаю противоречивые результаты от симулятора и инструментов: когда я задал этот вопрос, приложение запускалось в симуляторе примерно через 10 секунд (по Time Profiler), используя приведенный выше код.
Но сегодня, используя тот же код, что и выше, приложение запускается в симуляторе через 900 мс, даже если оно выполняет временную предварительную выборку для всех объектов и не блокирует пользовательский интерфейс.
Я приложил несколько свежих скриншотов:
РЕДАКТИРОВАНИЕ 2: я перезагрузил симулятор, и результаты оказались интригующими: после выполнения операции импорта и выхода из приложения первый запуск выглядел так: После небольшой прокрутки: Вот что происходит при втором запуске: После пятого запуска:
РЕДАКТИРОВАТЬ 3: Запустив приложение в седьмой и восьмой раз, я получаю следующее: