Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically setting fetchLimit for NSFetchedResultsController

I'm using am NSFetchedResultsController to populate data onto a UITableView. It's a simple chat app and I want to load the latest 25 messages onto the table first and load more as the user scrolls up to see older messages (the chat message are in a ascending order).

I call a method that will setFetchLimit: for the NSFetchedResultsController in the willDisplayCell: like so....

- (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 row of the UITableView has been displayed, getMoreMessages will try to reset the fetchLimit reload the UITableView like so.....

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

However, it doesn't seem to be working, the table data will not change. The initial NSFetchRequest is set like 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 one dynamically change the fetchLimit for an NSFetchedResultsController?

Any hits would be awesome! Thanks!

like image 346
Jiho Kang Avatar asked Jul 20 '11 01:07

Jiho Kang


2 Answers

Instand using setFetchLimit, using setBatchSize, see below for detail answer.

The count of the fetchedObjects array might not what you want to do, since it does not update the changes from the persistent store. From NSFetchedResultsController documentation:

The results array only includes instances of the entity specified by the fetch request (fetchRequest) and that match its predicate. (If the fetch request has no predicate, then the results array includes all instances of the entity specified by the fetch request.)

The results array reflects the in-memory state of managed objects in the controller’s managed object context, not their state in the persistent store. The returned array does not, however, update as managed objects are inserted, modified, or deleted.

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

like image 63
Jiejing Zhang Avatar answered Oct 03 '22 19:10

Jiejing Zhang


figured this one out. looks like I have to run performFetch: after I change the fetchLimit. :D

[self.resultsController.fetchRequest setFetchLimit:maxListItems];
[self.resultsController performFetch:&error];
like image 36
Jiho Kang Avatar answered Oct 03 '22 18:10

Jiho Kang