• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 刷新未绑定(bind)到 uitableview 的 nsfetchedresultscontroller

[复制链接]
菜鸟教程小白 发表于 2022-12-13 05:43:28 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在编写一个使用许多 NSFetchedResultsControllers (FRC) 的应用程序,每个应用程序用于我的数据模型中的不同托管对象子类。其中几个 FRC 是 UITableViewControllers 的一部分,但有几个不是。我有两个问题:第一,当我向 MOC 添加新对象时,为什么我的一个 FRC 没有更新,第二,我是否应该为此目的使用 FRC?我认为它可以让我不必在整个代码中放置获取请求,但也许只有将 FRC 与 tableview 或其他此类对象一起使用才有意义。

所以,这里是详细信息。

不绑定(bind)到 tableview 的 FRC 之一是跟踪时间表的 FRC。 SetScheduleViewController 具有以下属性(以及其他属性),这些属性是通过父 View Controller 传入的:

  @property (weak, nonatomic) NSFetchedResultsController *scheduleFetchedResultsController;
  @property (weak, nonatomic) NSManagedObjectContext *managedObjectContext;

这个 FRC 是由另一个对象(它维护一个指向它的强指针)通过以下代码创建的

- (NSFetchedResultsController *)scheduleFetchedResultsController  {


    if (_scheduleFetchedResultsController != nil) {
        return _scheduleFetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName"Schedule" inManagedObjectContext:self.managedObjectContext];

    [fetchRequest setEntity:entity];

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

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey"start" ascending:NO];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *fRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];


    NSError *error = nil;
    if (![fRC performFetch:&error]) {
        IFLErrorHandler *errorHandler;
        [errorHandler reportErrorToUser:error];
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    self.scheduleFetchedResultsController = fRC;

    return self.scheduleFetchedResultsController;
}

(顺便说一句:cacheName 设置为 nil 的原因是我似乎只能将缓存名称分配给此应用程序中的众多 FRC 中的一个,或者应用程序崩溃......如果只有一个 FRC给定一个缓存名称,其余的缓存名称设置为 nil,一切似乎都很好,尽管我担心没有缓存,随着持久存储大小的增长,性能可能会很糟糕......但这是另一回事)

SetScheduleViewController 中,可以创建或删除一个计划,并在加载SetScheduleViewController 时加载最近创建的计划。创建计划时,会创建一个新的计划管理对象,然后将 MOC 保存如下:

 Schedule *newSchedule= [NSEntityDescription insertNewObjectForEntityForName"Schedule" inManagedObjectContext:self.managedObjectContext];
 newSchedule.start=newStartTime; 
 //etc

  NSError *saveError;
    if (![self.managedObjectContext save:&saveError]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", saveError, [saveError userInfo]);
        abort();

这成功保存了新的 MO,但 FRC 没有更新...我已经检查了几种方法...例如,如果在保存新计划后我重新输入 SetScheduleViewController 并检查 [[self.scheduleFetchedResultsController fetchedObjects] count] 它没有增加。但是,如果我退出应用程序并再次打开它,你瞧,FRC 获取的对象计数会增加,并且新对象确实存在。

我应该注意到 scheduleFetchedResultsController 没有分配委托(delegate),这与 FRC 附加到 tableviewcontrollers 不同,它们都可以正常工作。我没有分配委托(delegate),因为据我所知,tableviewcontrollers 中的 FRC 委托(delegate)方法仅在 FRC 更改内容时处理更新 tableview...我没有看到任何委托(delegate)方法添加新对象并保存 MOC 时刷新 FRC 本身。

所以,我的两个问题又是:1) 为什么 FRC 不刷新(以及我如何让它刷新),2) 使用 FRC 来管理未绑定(bind)的托管对象的获取结果是否有意义到 tableview,我是否应该在每次需要访问对象列表时简单地从 MOC 执行新的提取?

非常感谢任何帮助。



Best Answer-推荐答案


NSFetchedResultsController 文档中指出,如果没有设置委托(delegate),FRC 处于“无跟踪”模式。此外,委托(delegate)必须至少实现一种变更跟踪委托(delegate)方法才能启用变更跟踪。

委托(delegate)不必是表格 View Controller ,因此您可以使用您的 SetScheduleViewController 作为委托(delegate),只需实现 controllerDidChangeContent: 委托(delegate)方法。在该方法中,更新的 fetchedObjects 是可用的,你可以例如更新 View 中的任何 UI 元素 Controller 。

更新:从 parentVC 传递 FRC 没有多大意义。 每个 View Controller 都应该有自己的 FRC。所以 scheduleFetchedResultsController 应该是 childVC 中的一个方法。由于 FRC 是在 getter 方法中“延迟”创建的,因此必须在某个地方调用 getter。

在 TableView Controller 的情况下,发生这种情况是因为所有 TableView 数据源方法 访问 self.fetchedResultsController

如果您的 childVC 不访问 self.fetchedResultsController 那么 FRC 不会被创建。这可能是在 viewDidLoad 中调用 [self.fetchedResultsController performFetch:&error] 的原因,正如另一个答案中所建议的那样,解决了您的问题。

委托(delegate)方法 controllerDidChangeContent: 如果结果会被调用 在 childVC 的生命周期内设置更改。这就是使用 FRC 的意义所在。

如果您只想在加载 childVC 时获取当前对象集,那么 你不需要 FRC,你可以执行一个简单的 fetch,例如在 viewDidLoad.

关于ios - 刷新未绑定(bind)到 uitableview 的 nsfetchedresultscontroller,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20604490/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap