我想在后台加载Core Data对象,完成后应重新加载TableView。下面的代码给出了一个空tableView:
class ViewController: UIViewController {
var fetchRequest: NSFetchRequest<Venue>!
var venue:[Venue] = []
var coreDataStack: CoreDataStack!
override func viewDidLoad() {
super.viewDidLoad()
fetchRequest = Venue.fetchRequest()
coreDataStack.storeContainer.performBackgroundTask {(context) in
do {
self.venue = try context.fetch(self.fetchRequesrt)
} catch {
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
但是如果我们在上面没有chunk的viewDidLoad()中编写代码,那么一切正常,tableView就会填充数据:
venue = try! coreDataStack.managedContext.fetch(fetchRequesrt)
tableView.reloadData()
上面的代码有什么问题? 对于建议,我将非常感激!
编辑。这是正确的解决方案:
class ViewController: UIViewController {
var fetchRequest: NSFetchRequest<Venue>!
var venue:[Venue] = []
var coreDataStack: CoreDataStack!
override func viewDidLoad() {
super.viewDidLoad()
fetchRequest = Venue.fetchRequest()
coreDataStack.storeContainer.performBackgroundTask {(context) in
do {
let venue = try context.fetch(self.fetchRequesrt)
venue.map {$0.objectID}.forEach{self.venue.append(self.coreDataStack.managedContext.object(with: $0) as! Venue)}
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
...
}
}
}
}
使用NSAsynchronousFetchRequest类的另一个解决方案。上面的例子如下所示:
class ViewController: UIViewController {
var fetchRequesrt: NSFetchRequest<Venue>!
var venue:[Venue] = []
var asyncFetchRequest: NSAsynchronousFetchRequest<Venue>!
var coreDataStack: CoreDataStack!
fetchRequest = Venue.fetchRequest()
override func viewDidLoad() {
super.viewDidLoad()
asyncFetchRequest = NSAsynchronousFetchRequest(fetchRequest:fetchRequest, completionBlock: { [unowned self]
(result: NSAsynchronousFetchResult) in
guard let venue = result.finalResult else { return }
self.venue = venue
self.tableView.reloadData()
})
do {
try coreDataStack.managedContext.execute(asyncFetchRequest)
} catch {
...
}
}
}
答案 0 :(得分:2)
每当与Core Data和NSFetchedResultController
进行交互时,您都应该使用TableView
。它比您自己获取数据更加稳定和优化。
我对你的代码感到很困惑,我从来没有见过像这样的解决方案。也许你应该使用闭包函数和完成后调用reloadData,或者把整个块放到beginUpdates
这样:
self.tableView.beginUpdates()
coreDataStack.storeContainer.performBackgroundTask {(context) in
do {
self.venue = try context.fetch(self.fetchRequesrt)
} catch {/*error goes here*/}
}
self.tableView.endUpdates()
无论如何,我强烈建议您使用NSFetchedResultsController
,因为它更容易执行backgroundTasks。