Dynamically configure fetchLimit for NSFetchedResultsController

I am using am NSFetchedResultsController to populate data in a UITableView. This is a simple chat application, and I want to first load the last 25 messages into a table and load more when the user scrolls to old messages (the chat message is in ascending order).

I call the method that will be setFetchLimit: for NSFetchedResultsController in willDisplayCell: like this ....

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

when the first line of the UITableView was displayed, getMoreMessages will attempt to reset fetchLimit, reloading the UITableView this way .....

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

However, it does not seem to work, the table data will not change. The source NSFetchRequest is set so ...

 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; 

And back to the question.

How can I dynamically change fetchLimit for NSFetchedResultsController?

Any punches would be awesome! Thanks!

+6
source share
2 answers

figured it out. it looks like I need to run performFetch: after changing fetchLimit .: D

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

Instand using setFetchLimit using setBatchSize , see below for a detailed answer.

The amount of the fetchedObjects array may not match what you want to do, because it does not update the changes in persistent storage. From the NSFetchedResultsController documentation:

The result array includes only instances of the object specified in the fetchRequest request and which match its predicate. (If the selection request does not have a predicate, then the result array includes all instances of the object specified in the selection request.)

The array of results reflects the state of the managed objects in memory in the context of the managed objects of the controllers, and not their state in the persistent storage. However, the returned array is not updated, since managed objects are inserted, modified, or deleted.

If you want to get only 20 objects, set the NSFetchRequest fetch limit. If you want to store only 20 objects in memory, use the setBatchSize of the NSFetchRequest object.

+6
source

Source: https://habr.com/ru/post/893116/


All Articles