Prevent/Postpone table在 table 不可见时查看来自 NSFetchedResultsController 的更新
Prevent/Postpone tableview updates from NSFetchedResultsController when table is not visible
Xcode11.0
Swift 5.1
我正在使用 Core Data 开发 "simple" 应用程序。
单个核心数据实体名为主题,包括标题(字符串)、详细信息(字符串)和收藏夹(布尔)
我正在使用带有 3 个选项卡的自定义 UITabBarController - Random Topic
、Favorite Topics
和 All Topics
Favorite Topics 和 All Topics 是共享相同子类的 UITableView,TopicsViewController
。
使用自定义 TopicTabBarController
我在 TopicsViewController 中设置了一个 属性,基于选项卡,它确定谓词是否与共享此控制器的两个选项卡的 FetchRequest 一起使用。
即使使用 FRC 缓存,这也能按预期工作(我是 Swift 的新手!)
如果某个主题在任何视图中被收藏,收藏主题和所有主题中的 tableView 都会更新以反映该更改。这正是我想要的。
问题是我收到一条警告,说 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
处设置了一个符号断点,但目前我有点难以理解它。
如果未加载视图,我尝试从 FRC 委托方法提前返回,但这显然不是解决方案。就像我说的,这对我来说是全新的。
我认为将 FRC Delegate 设置为 nil 并返回到 self as suggested in this post 会有所帮助,但这只会阻止 managedObjectContext 保存(至少这是我在 Navicat 中看到的)。我可以单步执行代码并查看控制器 class 的正确实例正在根据我为谓词设置的自定义 属性 进行操作。
这是该部分的相关代码:
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 的要点。我发现这样阅读起来容易多了。
我也是刚刚在 Apple Dev 论坛上看到 this post。看起来是同样的问题,未解决。
老实说,我不知道这些信息是太多了还是太少了。真的希望我在尝试解释问题时偶然发现解决方案。
感谢您的宝贵时间。
不管它的价值如何,我收到了同样的警告,我能够通过执行与您尝试的非常相似的操作来修复它。基本上唯一的区别是 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
}
...虽然我认为执行提取会同样有效?
Xcode11.0
Swift 5.1
我正在使用 Core Data 开发 "simple" 应用程序。
单个核心数据实体名为主题,包括标题(字符串)、详细信息(字符串)和收藏夹(布尔)
我正在使用带有 3 个选项卡的自定义 UITabBarController - Random Topic
、Favorite Topics
和 All Topics
Favorite Topics 和 All Topics 是共享相同子类的 UITableView,TopicsViewController
。
使用自定义 TopicTabBarController
我在 TopicsViewController 中设置了一个 属性,基于选项卡,它确定谓词是否与共享此控制器的两个选项卡的 FetchRequest 一起使用。
即使使用 FRC 缓存,这也能按预期工作(我是 Swift 的新手!)
如果某个主题在任何视图中被收藏,收藏主题和所有主题中的 tableView 都会更新以反映该更改。这正是我想要的。
问题是我收到一条警告,说 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
处设置了一个符号断点,但目前我有点难以理解它。
如果未加载视图,我尝试从 FRC 委托方法提前返回,但这显然不是解决方案。就像我说的,这对我来说是全新的。
我认为将 FRC Delegate 设置为 nil 并返回到 self as suggested in this post 会有所帮助,但这只会阻止 managedObjectContext 保存(至少这是我在 Navicat 中看到的)。我可以单步执行代码并查看控制器 class 的正确实例正在根据我为谓词设置的自定义 属性 进行操作。
这是该部分的相关代码:
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 的要点。我发现这样阅读起来容易多了。
我也是刚刚在 Apple Dev 论坛上看到 this post。看起来是同样的问题,未解决。
老实说,我不知道这些信息是太多了还是太少了。真的希望我在尝试解释问题时偶然发现解决方案。
感谢您的宝贵时间。
不管它的价值如何,我收到了同样的警告,我能够通过执行与您尝试的非常相似的操作来修复它。基本上唯一的区别是 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
}
...虽然我认为执行提取会同样有效?