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

ios - NSFetchedResultsControllers controllerDidChangeContent 方法中的无限循环

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

我有 UITableViewController 表并使用 NSFetchedResultsController 从 Core Data 获取行。我的 tableView 负责分层数据。每个行位置代表层(在零行最高层,n - 最低行)。假设我们有一个名为 Layers *layers 的对象。当我创建新层时,它需要转到表中的第一行(indexPath.row == 0)并且需要获取layers.layer.position = 0。当我创建新层或进行一些其他更改(移动、删除)时,我需要刷新核心数据对象 layers(每个层都需要获取新的位置值)。但是,如果我通过调用 [self updateLayersPosition] 方法在 controllerDidChangeContent 方法旁边刷新图层位置,它会进入无限循环,因为每次在每个旧图层值更改时它都会返回相同的 controllerDidChangeContent 方法一次又一次。所以问题是如何将表格行或获取的 Controller indexPath.rowlayers.layer.position “绑定(bind)”?也许我可以停止 fetchedresultscontroller 获取,进行更新然后再次开始获取?或者也许有其他方法可以做到这一点?

代码如下:

-(void)updateLayers{
    for (int i = 0; i < [self.tableView numberOfRowsInSection:0]; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i 
                                                    inSection:0];
            ((Layer *)[self.fetchedResultsController objectAtIndexPath:indexPath]).layer.position = i;
    }
}

- (void)controllerDidChangeContentNSFetchedResultsController *)controller
{
    [self updateLayers];
    [self.tableView endUpdates];
}



Best Answer-推荐答案


NSFetchedResultsControllerDelegate 中的所有willChange/didChange 方法都是在你修改Core Data 对象后调用的。所以如果你修改了controllerDidChangeContent:里面的任何NSManagedObject,都会再次触发controllerDidChangeContent:,导致死循环。

您可以将这些委托(delegate)回调视为一个 Controller ,说“您已经更改了 Core Data 模型中的某些内容,现在让我们更新 UI(UITableView)。您应该遵循的一般模式是:

  • NSManagedObjects
  • 中进行一项或多项更改(添加、修改、删除)
  • 保存NSManagedObjectContext
  • NSFetchedResultsControllerDelegate 的方法中:更新 UITableView 以反射(reflect)更改(添加、重新加载、删除 TableView 行)

所以你可能想做这样的事情:

//in the method in which you add a new Layer object
- (void)addLayer {
  Layer *layer = [NSEntityDescription insertNewObjectForEntityForName"Layer" inManagedObjectContext:context];
  //recalculate the position of all the other layers
  //save NSManagedObjectContext
}

关键是添加新层后立即更新每一层的position,然后保存上下文。然后 NSFetchedResultsController 将按照您的需要将图层的位置“绑定(bind)”到表中的行(我假设您在使用的排序描述符中使用 position 属性在获取请求中)。如果您按照 documentation 中的建议实现这些 NSFetchedResultsControllerDelegate 方法,它应该做的工作:

- (void)controllerWillChangeContentNSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

- (void)controllerNSFetchedResultsController *)controller didChangeObjectid)anObject
    atIndexPathNSIndexPath *)indexPath forChangeTypeNSFetchedResultsChangeType)type
    newIndexPathNSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                       withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                       withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
                  atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                       withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                       withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContentNSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

关于ios - NSFetchedResultsControllers controllerDidChangeContent 方法中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25103478/

回复

使用道具 举报

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

本版积分规则

关注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