Xcode 11.0
swift 5.1
我正在使用 Core Data 开发一个“简单”的应用程序。
单个 Core Data 实体名为 Topic,包含 Title(字符串)、Details(字符串)和 isFavorite( bool )
我正在使用带有 3 个选项卡的自定义 UITabBarController - Random Topic
、Favorite Topics
和 All 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/