Почему NSFetchedResultsController загружает все строки при настройке размера пакета выборки?

#iphone #objective-c #core-data

#iPhone #objective-c #core-data

Вопрос:

Для NSFetchedResultsController установлено значение 5 для размера пакета выборки. Мы замечаем медленную загрузку, поэтому включаем SQLDebug. По какой-то причине он загружает 5 строк одновременно, но делает это для всех 100 строк при начальной загрузке. После загрузки кажется, что он загружает 5 строк одновременно.

При просмотре консоли я вижу, что запрос выполняется 20 раз; всего 100 строк. Я бы ожидал, что это будет выполняться 1 раз с первыми 5 строками, и при прокрутке будет загружено больше строк. Я также попытался изменить размер выборки, и он ведет себя так же.

Настройка контроллера полученных результатов приведена ниже.

 - (NSFetchedResultsController*) fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    [NSFetchedResultsController deleteCacheWithName:@"Root"];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"Message" inManagedObjectContext:_context];

    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"conversation = %@", conversation];

    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] 
                              initWithKey:@"timestamp" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:5];

    NSFetchedResultsController *theFetchedResultsController = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                        managedObjectContext:_context sectionNameKeyPath:nil 
                                                   cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    [sort release];
    [fetchRequest release];
    [theFetchedResultsController release];

    return _fetchedResultsController;    

}
 

Комментарии:

1. Опубликуйте код, в котором вы фактически выполняете выборку в NSFetchedResultsController.

2. Вы хотели что-то другое, чем то, что указано выше? Спасибо!

Ответ №1:

Мы используем NSFetchedResultsController в сочетании с tableview. Tableview запросит у NSFetchedResultsController столько строк, сколько ему нужно, чтобы заполнить строки, которые, по его мнению, ему нужно будет показать и сохранить под рукой по соображениям производительности. Искусственно уменьшая размер пакета, вы заставляете NSFetchedResultsController совершать больше обходов обратно в хранилище.

Установите для него значение 100 или около того и посмотрите, какова ваша производительность. Если у вас возникли проблемы с производительностью при размере пакета 100, вам, возможно, придется нормализовать вашу основную модель данных. Посмотрите видеоролики WWDC о Core Data за 2010 год. В нем есть отличное видео по оптимизации основных данных и выборок, связанных с NSFetchedResultsController.

Удачи