更改 NSFetchedResultsController 的 Fetch Request 和重新加载表数据的方法

Posted

技术标签:

【中文标题】更改 NSFetchedResultsController 的 Fetch Request 和重新加载表数据的方法【英文标题】:Recipes for changing the Fetch Request for NSFetchedResultsController and reloading table data 【发布时间】:2012-04-16 08:39:43 【问题描述】:

从苹果文档Modifying the Fetch Request 我看到可以将NSFetchRequest 更改为NSFetchedResultsController。步骤很容易设置。

在调用performFetch: 之后,我认为有必要在表格视图上调用reloadData。如何进行这样的调用?

阅读了一些 *** 主题后,我发现在大多数情况下调用该方法应该可以工作。但是有没有正确的方法呢?

在How to switch UITableView's NSFetchedResultsController (or its predicate) programmatically?,TechZen 写道:

只需确保在您之前向 tableview 本身发送 beginUpdates 完成后交换控制器,然后是 endUpdates。这 当 FRC 正在被换出。然后调用 reloadData。

你能具体解释一下这是什么意思吗?

【问题讨论】:

【参考方案1】:

假设生成正确 fetch 的逻辑(某种条件语句)在 NSFetchedResultsController 实例的 getter 中。那么就真的很简单了

self.fetchedResultsController = nil; // this destroys the old one
[self.tableview reloadData]; 
// when the table view is reloaded the fetchedResultsController will be lazily recreated

编辑:添加我所做的事情的完整代码示例。基本上我有一个 NSDictionary entityDescription,它保存值来自定义 NSFetchedResultsController 的创建。如果我想更改 fetchRequest,我更改我的 entityDescription 变量以指示新值并覆盖设置器以重置 fetchedResultsController 并重新加载表。它为您提供了基本概念。

- (NSFetchedResultsController *)fetchedResultsController 

    if (__fetchedResultsController != nil) 
        return __fetchedResultsController;
    
    if (self.entityDescription == nil) 
        return nil;
    
    // Set up the fetched results controller.
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[self.entityDescription objectForKey:kEntityName]];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    if ([[self.entityDescription objectForKey:kEntitySortField] isEqualToString:@"null"] == NO) 
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[self.entityDescription objectForKey:kEntitySortField] ascending:YES];
        NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
        [fetchRequest setSortDescriptors:sortDescriptors];
    

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                                                                managedObjectContext:self.moc sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    

    return __fetchedResultsController;


- (void)setEntityDescription:(NSDictionary *)entityDescription

    _entityDescription = entityDescription;
    self.fetchedResultsController = nil;
    [self.tableView reloadData];

【讨论】:

感谢您的回复。你能更好地解释你的意思吗?干杯。

以上是关于更改 NSFetchedResultsController 的 Fetch Request 和重新加载表数据的方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 3 中难以配置 NSFetchedResultsController

如何根据计算的属性过滤来自 NSFetchedResultsController 的结果?

为啥 beginUpdates/endUpdates 会重置表视图位置以及如何阻止它这样做?

HAC 集群更改 IP(单节点更改全部节点更改)

更改fancybox iframe的大小-我可以更改宽度但不能更改高度?

在运行时更改方向更改 ViewControllers