【发布时间】:2018-04-08 06:02:04
【问题描述】:
我正在使用 Swift 4 构建具有 UITableViewController 的单视图 iOS 11 应用程序,该应用程序也定义为 delegate 用于 NSFetchedResultsController。
class MyTVC: UITableViewController, NSFetchedResultsControllerDeleagate {
var container:NSPersistentContainer? =
(UIApplication.shared.delegate as? AppDelegate)?.persistentContainer
var frc : NSFetchedResultsController<Student>?
override func viewDidLoad() {
container?.performBackgroundTask { context in
// adds 100 dummy records in background
for i in 1...100 {
let student = Student(context: context)
student.name = "student \(i)"
}
try? context.save() // this works because count is printed below
if let count = try? context.count(for: Student.fetchRequest()) {
print("Number of students in core data: \(count)") // prints 100
}
} // end of background inserting.
// now defining frc:
if let context = container?.viewContext {
let request:NSFetchRequest<Student> = Student.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
frc = NSFetchedResultsController<Student> (
fetchRequest: request,
managedObjectContext: context,
sectionNameKeyPath: nil,
cacheName: nil )
try? frc?.performFetch() // this works and I get no errors
tableView.reloadData()
frc.delegate = self
} // end of frc definition
}
}
如果我使用viewContext 添加一行Student,frc 将触发所需的方法以在tableView 中显示它。然而,100 个虚拟行未显示。事实上,如果我试图在插入完成后告诉 tableview 重新加载,我的应用程序开始表现得很奇怪并变得有问题,并且没有做它应该做的事情(即:不删除行,不编辑等) .
但是如果我重新启动我的应用程序,而不调用虚拟插入,我可以看到前一次运行插入的 100 行。
唯一的问题是我无法从后台线程调用tableView.reloadData(),所以我尝试这样做:
// after printing the count, I did this:
DispatchQueue.main.async { [weak self] in
self?.tableView.reloadData() // causes UI to behave weirdly
}
然后我尝试调用viewContext.perform 在正确的线程中重新加载表格视图
func viewDidLoad() {
// code for inserting 100 dummy rows in background thread
// code for defining frc and setting self as delegate
if let context = container?.viewContext {
context.perform { [weak self] in
self?.tableView.reloadData() // that also causes UI to behave weirdly
}
}
}
如何告诉我的 tableview 以线程安全的方式重新加载和显示 100 个虚拟行?
【问题讨论】:
-
在执行获取之前尝试设置委托。
-
@JonRose 我试过了。如果我在执行调用之后设置委托,则委托方法不会触发。所以,刷新不会发生,应用程序更容易出错
-
@Ahmad “导致 UI 行为怪异”是什么意思?
-
@staticVoidMan 动画变得迟缓并且表格行上的删除按钮不会触发委托方法commiteditingstyle
-
@Ahmad 您可以创建一个调试存储库并将其添加到您的问题中吗?我认为如果我们可以在调试 repo 上为您提供帮助会更快。
标签: swift uitableview core-data