保存核心数据中断获取请求

Posted

技术标签:

【中文标题】保存核心数据中断获取请求【英文标题】:Saving Core Data breaks fetch request 【发布时间】:2017-06-28 13:18:43 【问题描述】:

我对 CoreData 有一个奇怪的问题。当我第一次加载数据时,一切似乎都正常,但在保存数据后,所有后续的 fetch 请求都停止工作(或者更确切地说返回空)。

我从 this 项目复制了 CoreDataStack,这是 udacity 的一个示例项目。它包含一个保存辅助函数。

func save() 
        context.performAndWait() 
            if self.context.hasChanges 
                do 
                    try self.context.save()
                 catch 
                    fatalError("Error while saving main context: \(error)")
                
                // now we save in the background
                self.persistingContext.perform() 
                    do 
                        try self.persistingContext.save()
                     catch 
                        fatalError("Error while saving persisting context: \(error)")
                    
                
            
        
    

在我的视图控制器内部,我可以使用如下代码为不同的谓词正常运行获取请求。

fetchedResultsController?.fetchRequest.predicate = NSPredicate(format: "fromDatetime >= %@ AND fromDatetime < %@", argumentArray: [selectionTime, selectionTime + 3600_000])
fetchedResultsController?.managedObjectContext.refreshAllObjects()
let m = fetchedResultsController?.fetchedObjects as! [Measurement]
print("number of elements in m: \(m.count)")

使用测试按钮保存数据后。

@IBAction func testAction(_ sender: Any) 
    // test action
    print("test clicked")
    let delegate = UIApplication.shared.delegate as! AppDelegate
    let stack = delegate.stack
    stack.save()

所有后续的获取请求都是空的。我还创建了另一个 ViewController,它实现了UITableViewController,包含存储在设备上的所有数据。如果我打开它,数据仍然在那里正确显示,即使在保存之后也是如此。 什么可能导致这种行为?

【问题讨论】:

【参考方案1】:

这可能是由于 performAndWait() 导致的死锁导致 UI 线程阻塞的结果,因为它在不同的队列中运行并且并非全部共享同一个公共队列。要解决此问题,请为 managedObjectContext 设置实例变量并始终引用此上下文以避免阻塞对 managedObjectContext 的访问。

 lazy var mainContext: NSManagedObjectContext = 
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
return appDelegate!.managedObjectContext
 

查看解决类似问题的另一个question。

【讨论】:

以上是关于保存核心数据中断获取请求的主要内容,如果未能解决你的问题,请参考以下文章

核心数据:NSManagedObjectContext 未保存/获取请求失败,直到应用退出和重新启动

核心数据请求和保存的最佳实践

对核心数据请求进行升序排序

通过将新项目保存到具有继承的过滤获取请求的CoreData错误

如何获取HTTP请求响应问号

使用 RESTkit PUT 请求、更改标头并将响应保存在核心数据中