の親子コンテキストについて少し混乱していManagedObjectContext
ます。
子コンテキストをセットアップして親コンテキストを設定すると、子コンテキストには親コンテキストのすべてのオブジェクトが含まれますか? で作成されるストックCore Data
メソッドを使用していますが、をメインAppDelegate
に変更しました。ConcurrencyQueue
データベースを更新するはずの私の方法では:
- 子コンテキストの作成、親コンテキストの設定
- 子コンテキストでブロックを実行
- 親コンテキストからフェッチ
- 子コンテキストでオブジェクトを作成または更新する
- 子コンテキストで保存を呼び出す
- 子コンテキストの保存を処理する通知リスナーを用意する
- 親コンテキストを保存
私の問題は、子コンテキストに何かを保存しているように見えないことです。Update または Create 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()
}
}
更新を処理するデータベース クラス
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)
}