The*_*mad 5 core-data nsmanagedobjectcontext ios managedobjectcontext swift
对于父母/子女的情境,我有点困惑ManagedObjectContext.
当我设置子上下文并设置父上下文时,子上下文是否包含父上下文的所有对象?我正在使用在Core Data其中创建的库存方法AppDelegate,但我将其更改ConcurrencyQueue为main.
在我应该更新db的方法中:
我的问题是,它看起来我没有保存任何内容到子上下文.我没有得到更新或创建ChatMessage的println消息.我在这做错了什么?
AppDelegate核心数据方法
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
NSNotificationCenter.defaultCenter().addObserver(self, selector: "contextDidSave:", name: NSManagedObjectContextDidSaveNotification, object: nil)
return managedObjectContext
}()
func contextDidSave(notification: NSNotification) {
let sender = notification.object as! NSManagedObjectContext
if sender != managedObjectContext {
managedObjectContext?.mergeChangesFromContextDidSaveNotification(notification)
println("Core Data: merging changes from child context")
saveContext()
}
}
Run Code Online (Sandbox Code Playgroud)
处理更新的数据库类
lazy var parentContext: NSManagedObjectContext? = {
if let managedObjectContext = self.appDelegate.managedObjectContext {
return managedObjectContext
}
else {
return nil
}
}()
func updateMessage(chatMessage: ChatMessage) {
if chatMessage.id.isEmpty { return }
let childContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
childContext.parentContext = parentContext
childContext.performBlock({
let objectIdDesc = NSExpressionDescription()
objectIdDesc.name = "objectID"
objectIdDesc.expression = NSExpression.expressionForEvaluatedObject()
objectIdDesc.expressionResultType = NSAttributeType.ObjectIDAttributeType
let fetchRequest = NSFetchRequest(entityName: "ChatMessage")
fetchRequest.predicate = NSPredicate(format: "id == %@", chatMessage.id)
fetchRequest.propertiesToFetch = [objectIdDesc]
fetchRequest.resultType = .DictionaryResultType
var error: NSError?
if let results = self.parentContext!.executeFetchRequest(fetchRequest, error: &error) {
if error == nil {
if !results.isEmpty {
if let objectId = results[0].valueForKey("objectID") as? NSManagedObjectID {
let fetched = childContext.objectWithID(objectId) as! ChatMessage
fetched.id = chatMessage.id
fetched.senderUserId = chatMessage.senderUserId
fetched.senderUsername = chatMessage.senderUsername
fetched.receiverUserId = chatMessage.receiverUserId
fetched.receiverUsername = chatMessage.receiverUsername
fetched.messageType = chatMessage.messageType
fetched.message = chatMessage.message
fetched.timestamp = chatMessage.timestamp
fetched.filepath = chatMessage.filepath
println("Updated ChatMessage: \(fetched.id)")
}
else {
var newMessage = NSEntityDescription.insertNewObjectForEntityForName("ChatMessage", inManagedObjectContext: childContext) as! ChatMessage
newMessage.id = chatMessage.id
newMessage.senderUserId = chatMessage.senderUserId
newMessage.senderUsername = chatMessage.senderUsername
newMessage.receiverUserId = chatMessage.receiverUserId
newMessage.receiverUsername = chatMessage.receiverUsername
newMessage.messageType = chatMessage.messageType
newMessage.message = chatMessage.message
newMessage.timestamp = chatMessage.timestamp
newMessage.filepath = chatMessage.filepath
println("Create ChatMessage: \(newMessage.id)")
}
}
}
else {
println("Fetch Message Object ID Error: \(error?.localizedDescription)")
}
}
})
childContext.save(nil)
}
Run Code Online (Sandbox Code Playgroud)
创建子上下文然后从父上下文中获取似乎没有多大意义.我不相信这是儿童背景的方式被设想使用的方式.
为了消除混淆:在从父上下文创建子上下文之后,该子上下文与父上下文具有相同的"状态".只有当两个上下文执行不同的操作(创建,修改,删除对象)时,两个上下文的内容才会发生分歧.
因此,对于您的设置,请执行以下操作:
在此阶段,尚未将任何内容保存到持久性存储中.通过子保存,更改只是"推送"到父上下文.你现在可以
将新数据写入持久性存储.然后
最好通过通知(例如NSManagedObjectContextDidSaveNotification).