开发者

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 = [[NSSortDescrip开发者_开发技巧tor 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!


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.


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];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜