swift - 当表不可见时防止/推迟从 NSFetchedResultsController 更新 TableView

标签 swift uitableview nsfetchedresultscontroller

Xcode 11.0

swift 5.1

我正在使用 Core Data 开发一个“简单”的应用程序。

单个 Core Data 实体名为 Topic,包含 Title(字符串)、Details(字符串)和 isFavorite( bool )

我正在使用带有 3 个选项卡的自定义 UITabBarController - Random TopicFavorite TopicsAll Topics

Favorite Topics 和 All Topics 是共享相同子类 TopicsViewController 的 UITableViews。

使用自定义 TopicTabBarController,我根据选项卡在 TopicsViewController 中设置了一个属性,该属性确定谓词是否与共享此 Controller 的两个选项卡的 FetchRequest 一起使用。

即使使用 FRC 缓存,这也能按预期工作(我是 Swift 的新手!)

如果某个主题在任何 View 上被收藏,收藏主题和所有主题中的 tableView 都会更新以反射(reflect)该更改。这正是我想要的。

问题是我收到一条警告,说 tableView 在不可见的情况下正在更新:

UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window).

我在 UITableViewAlertForLayoutOutsideViewHierarchy 处设置了一个符号断点,但目前我有点难以理解它。

如果未加载 View ,我尝试过从 FRC 委托(delegate)方法提前返回,但这显然不是解决方案。就像我说的,这对我来说是全新的。

我想将 FRC Delegate 设置为 nil 并返回到 self 作为 suggested in this post会有所帮助,但这只会阻止 managedObjectContext 保存(至少这是我在 Navicat 中看到的)。我可以单步执行代码并查看 Controller 类的正确实例正在根据我为谓词设置的自定义属性进行操作。

这是该部分的相关代码:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.fetchedResultsController.delegate = self
    self.performFetch()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.fetchedResultsController.delegate = nil
}

// MARK:- Helper methods
func performFetch() {

    do {
        try fetchedResultsController.performFetch()
    } catch {
        fatalCoreDataError(error)
    }
}

这是保存实体的地方,上面的代码不会发生这种情况:

@objc func toggleFavorite(_ sender: UIButton) {
    let buttonPosition = sender.convert(sender.bounds.origin, to: tableView)
    if let indexPath = tableView.indexPathForRow(at: buttonPosition) {
        let topic = fetchedResultsController.object(at: indexPath)
        topic.isFavorite = !topic.isFavorite
        try! managedContext.save()
    }
}

这是 more details 的要点.我发现这样阅读起来更容易。

我也刚遇到this post在 Apple Dev 论坛上。看起来是同一个问题,未解决。

老实说,我不知道这些信息是太多了还是太少了。真的希望我在尝试解释问题时偶然发现解决方案。

感谢您的宝贵时间。

最佳答案

不管它的值(value)如何,我收到了同样的警告,并且我能够通过执行与您尝试的非常相似的操作来修复它。基本上唯一的区别是 tableView.reloadData()

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    fetchedResultsController.delegate = self
    tableView.reloadData()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    fetchedResultsController.delegate = nil
}

...尽管我认为执行提取的工作方式是一样的?

关于swift - 当表不可见时防止/推迟从 NSFetchedResultsController 更新 TableView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58126306/

相关文章:

ios - NSRangeException',原因 : '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 . 。 1] 核心数据和 NSFR 错误

ios - NSFetchedResultsController 正在加载所有行,即使我已经设置了批处理

快速 fatal error : unexpectedly found nil while unwrapping an Optional value in adMob

arrays - 类型 'String?' 不符合协议(protocol) 'Equatable'

uiview - 如何更改 View 单击 UIAlertViewController 中的按钮

ios - UITableViewCellAccessoryDisclosureIndicator 未显示

ios - 在 Swift 中以编程方式将 UITableViewStyle 更改为 Plain?

iphone - UIATableView 始终命名为 "Empty list"

ios - 使用 NSPredicate 从 NSFetchedResultscontroller 更新 NSManagedObject 时出现 CoreData 错误

swift - NumberFormatter() - 可以用特定数量的空格填充吗?