在后台和 tableView.reloadData() 中获取核心数据对象
Posted
技术标签:
【中文标题】在后台和 tableView.reloadData() 中获取核心数据对象【英文标题】:Fetching Core Data object in the background and tableView.reloadData() 【发布时间】:2016-12-29 14:24:58 【问题描述】:我想在后台加载 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()
但是如果我们在 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.forEachself.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
...
【问题讨论】:
【参考方案1】:在与 Core Data 和 TableView
本身交互时,您应该使用 NSFetchedResultController
。它比您自己获取数据更加稳定和优化。
我对您的代码感到非常困惑,我从未见过这样的解决方案。也许您应该使用闭包和完成调用 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
,因为它更容易执行后台任务。
【讨论】:
以上是关于在后台和 tableView.reloadData() 中获取核心数据对象的主要内容,如果未能解决你的问题,请参考以下文章
[tableView reloadData] 和 runloop
使用通知中心和 tableview.reloaddata() 不刷新表视图
每次视图出现时 tableView.reloadData()
iOS TableView reloadData刷新列表cell乱跳tableview闪动的问题。