问题描述
我在将内容保存在后台时遇到问题.因此,我有2个与RxSwift链接的操作.前几项已保存,当我在主要上下文中获取它们时,所有信息均已存在.但是在第二个操作中,我获取了相同的对象,并使用更多信息对其进行了更新.现在,无论我在那做什么,它都永远不会更新实体.
I'm having a problem saving things in the background. So I have 2 operations that I chain with RxSwift.The first items are saved and when I fetch them on a main context all the information is there.But in the second operation I fetch the same object and I update it with more information.Now whatever I do there it never updates the entity.
这是我的核心数据代码:
This is my coredata code:
class CoreDataStack {
static let modelName = "Mo_Application"
static let model: NSManagedObjectModel = {
let modelURL = Bundle(for: CoreDataStack.self).url(forResource: modelName, withExtension: "momd")!
return NSManagedObjectModel(contentsOf: modelURL)!
}()
lazy var mainContext: NSManagedObjectContext = {
return self.storeContainer.viewContext
}()
lazy var storeContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: CoreDataStack.modelName, managedObjectModel: CoreDataStack.model)
container.loadPersistentStores { (_, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
func newDerivedContext() -> NSManagedObjectContext {
return self.storeContainer.newBackgroundContext()
}
func saveContext() throws {
try? self.saveContext(mainContext)
}
func saveAndWaitContext(_ context: NSManagedObjectContext) throws {
if context != mainContext {
try self.saveAndWaitDerivedContext(context)
return
}
context.performAndWait {
try? context.save()
}
}
func saveAndWaitDerivedContext(_ context: NSManagedObjectContext) throws {
context.performAndWait {
try? context.save()
try? self.saveAndWaitContext(self.mainContext)
}
}
}
我在第一次手术中要做的事情
What I do in the first operation:
let context = coreDataStack.newDerivedContext()
let object = Foo(context: context)
object.name = "Name 1"
try coreDataStack.saveAndWaitDerivedContext(context)
maybe(.success(self)) (RxSwift to complete)
在第二个操作中,我首先获取对象:
In the second operation I first fetch the object:
let context = coreDataStack.newDerivedContext()
let fetchRequest: NSFetchRequest<Foo> = Foo.fetchCreatedBy(user: user)
let objects: [Foo] = try context.fetch(fetchRequest)
let object = objects.first { $0.id == self.id }
if let object = object {
object.name = "Name updated"
}
try coreDataStack.saveAndWaitDerivedContext(context)
maybe(.success(self))
现在我对mainContext进行访存时,旧值仍然存在.
When I now do a fetch on my mainContext the old value is still there.
当我调用saveAndWaitDerivedContext时,背景上下文具有Changes.但是,当我保存mainContext时,它没有更改吗?正常吗?
When I call my saveAndWaitDerivedContext the background context hasChanges. But when I then save the mainContext it doesn't have changes? Is that normal?
我在做什么错了?
推荐答案
摘自 NSPersistentContainer.newBackgroundContext()
上的文档:
这表明您的背景上下文直接写到持久性存储中.如果您不将在后台上下文中所做的更改合并到其中,则主要上下文将不知道这一点.
This gives a hint that your background context writes directly into the persistent store. Main context will not know about this if you don't merge the changes made in the background context into it.
您应该从后台上下文中收听 NSManagedObjectContextDidSave
通知,并将对它的更改合并到主上下文中.
You should listen to NSManagedObjectContextDidSave
notification from the background context, and merge changes from it into the main context.
func saveAndWaitDerivedContext(_ context: NSManagedObjectContext) throws {
let observer = NotificationCenter.default.addObserver(forName: .NSManagedObjectContextDidSave, object: context, queue: .main) { (notification) in
self.mainContext.mergeChanges(fromContextDidSave: notification)
}
context.performAndWait {
try? context.save()
}
NotificationCenter.default.removeObserver(observer)
}
这篇关于CoreData backgroundContext保存不会保存并丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!