Динамическая настройка fetchLimit для NSFetchedResultsController

Я использую am NSFetchedResultsController для заполнения данных в UITableView. Это простое приложение для чата, и я хочу сначала загрузить последние 25 сообщений на таблицу и загрузить больше, когда пользователь прокручивает вверх, чтобы увидеть старые сообщения (сообщение чата в порядке возрастания).

Я вызываю метод, который будет setFetchLimit: для NSFetchedResultsController в willDisplayCell: вот так....

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row == 0)
    {
        [self performSelector:@selector(getMoreMessages) withObject:nil afterDelay:1.0];
    }
}

при отображении первой строки UITableView, getMoreMessages попытается сбросить fetchlimit перезагрузить UITableView так.....

- (void)getMoreMessages
{
    maxListItems += 25;
    NSLog(@"set maxListItems: %d", maxListItems);
    [self.resultsController.fetchRequest setFetchLimit:maxListItems];
    [self._tableView reloadData];
}

однако, похоже, он не работает, данные таблицы не будут меняться. Начальный NSFetchRequest устанавливается так...

NSFetchRequest *chatDataRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ChatData" inManagedObjectContext:appDelegate.managedObjectContext];
[chatDataRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(key != 0 OR messageNo != 0) and matchNo = %d", matchNo];
[chatDataRequest setPredicate:predicate];

NSSortDescriptor *sortDescripter1 = [[NSSortDescriptor alloc] initWithKey:@"status" ascending:YES];
NSSortDescriptor *sortDescripter2 = [[NSSortDescriptor alloc] initWithKey:@"messageNo" ascending:YES];
NSArray *sortDescripters = [[NSArray alloc] initWithObjects:sortDescripter1, sortDescripter2, nil];
[chatDataRequest setSortDescriptors:sortDescripters];
[sortDescripters release];
[sortDescripter1 release];
[sortDescripter2 release];

[chatDataRequest setFetchLimit:25];

NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:chatDataRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:nil cacheName:[NSString stringWithFormat:@"%d_chat.cache", matchNumber]];
[chatDataRequest release];
fetchedResultsController.delegate = self;
NSError *error;
BOOL success = [fetchedResultsController performFetch:&error];
if(!success) NSLog(@"error: %@", error);
self.resultsController = fetchedResultsController;

и вернемся к вопросу.

как можно динамически изменять fetchLimit для NSFetchedResultsController?

любые хиты были бы потрясающими! Спасибо!

2 ответов


понял этого. похоже, мне нужно запустить performFetch: после изменения fetchLimit. : D

[self.resultsController.fetchRequest setFetchLimit:maxListItems];
[self.resultsController performFetch:&error];

Instand с помощью setFetchLimit, используя setBatchSize см. ниже для деталей ответ.

счетчик массива fetchedObjects может быть не тем, что вы хотите сделать, так как он не обновляет изменения из постоянного хранилища. Из документации NSFetchedResultsController:

массив результатов включает только экземпляры сущности, заданной запросом fetch (fetchRequest) и соответствующие ее предикату. (Если запрос fetch не имеет предиката, то результаты массив включает в себя все экземпляры сущности, указанной в запросе выборки.)

массив результатов отражает состояние управляемых объектов в памяти в контексте управляемого объекта контроллера, а не их состояние в постоянном хранилище. Однако возвращаемый массив не обновляется при вставке, изменении или удалении управляемых объектов.

Если вы хотите получить только 20 объектов, установите предел выборки NSFetchRequest. Если вы хотите сохранить только 20 объектов память, используйте setBatchSize объекта NSFetchRequest.