为NSFetchedResultsController动态设置fetchLimit

Jih*_*ang 6 iphone objective-c ios

我正在使用NSFetchedResultsController将数据填充到UITableView上.这是一个简单的聊天应用程序,我想先将最新的25条消息加载到桌面上,然后在用户向上滚动以查看较旧的消息时加载更多消息(聊天消息按升序排列).

我为willDisplayCell中的NSFetchedResultsController调用了一个setFetchLimit的方法:就像这样....

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

当显示UITableView的第一行时,getMoreMessages将尝试重置fetchLimit重新加载UITableView,就像这样......

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

但是,它似乎不起作用,表数据不会改变.最初的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;
Run Code Online (Sandbox Code Playgroud)

回到这个问题.

如何动态更改NSFetchedResultsController的fetchLimit?

任何点击都会很棒!谢谢!

Jih*_*ang 7

想出这个.看起来我必须运行performFetch:更改fetchLimit之后.:d

[self.resultsController.fetchRequest setFetchLimit:maxListItems];
[self.resultsController performFetch:&error];
Run Code Online (Sandbox Code Playgroud)

  • 此外,请确保您重新加载UITableView后 (2认同)

Jie*_*ang 7

Instand使用setFetchLimit,使用setBatchSize,请参阅下面的详细解答.

fetchedObjects数组的计数可能不是您想要执行的操作,因为它不会更新持久性存储中的更改.来自NSFetchedResultsController文档:

结果数组仅包含由获取请求(fetchRequest)指定的实体的实例,并且与其谓词匹配.(如果获取请求没有谓词,则结果数组包括获取请求指定的实体的所有实例.)

结果数组反映了控制器的托管对象上下文中托管对象的内存中状态,而不是持久性存储中的状态.但是,返回的数组不会在插入,修改或删除托管对象时更新.

如果您只想获取20个对象,请设置NSFetchRequest的获取限制.如果只想在内存中保留20个对象,请使用NSFetchRequest对象的setBatchSize.