我正在构建一个 Apple Watch 应用程序,它通过 App Group 在 iPhone 目标和 Watch 目标之间共享核心数据上下文。下面的 WatchCoreDataProxy
是一个处理 Core Data 功能的自定义框架,将 App Group 称为两个目标之间的桥梁。我更新 iPhone 应用程序中的上下文并保存,然后将 Darwin 通知发布到 Watch,它从同一上下文获取更新的 NSManagedObjects。除了一个怪癖外,大多数一切都运行良好:
我在 Watch 中获取的 NSManagedObject(我们称它为 Parent
)包含与另一个 NSManagedObject(我们称它为 Child
)的一对多关系。我正在从 Watch 目标中获取 Parent
,并假设它的属性已保存到 Core Data 并反射(reflect)最新值。
Parent
的属性始终反射(reflect)从 Watch 获取时的更新值。但是 Child
关系对象没有。真正奇怪的是,对 Child
的更改会持续存在于 iPhone 应用程序方面,但不会存在于 Watch 中。我从 Watch 获取对象的代码如下所示:
let entityDesc = NSEntityDescription.entityForName("Parent", inManagedObjectContext: WatchCoreDataProxy.sharedInstance.managedObjectContext!)
let request: NSFetchRequest = NSFetchRequest()
request.entity = entityDesc
let predicate = NSPredicate(format: "loadedOnWatch == 1")
request.predicate = predicate
var error: NSError?
let array = WatchCoreDataProxy.sharedInstance.managedObjectContext!.executeFetchRequest(request, error: &error)! as NSArray
let parent: Parent = array[0] as! Parent
self.parentID = parent.objectID
self.parentTitleLabel.setText(parent.name) //reflects changes successfully
self.childArray = parent.children.sortedArrayUsingDescriptors([NSSortDescriptor(key: "position", ascending: true)]) as NSArray
let firstChild = self.intervalArray.objectAtIndex(0) as! Child
let title = firstChild.title
self.childTitleLabel.setText(title) //does not reflect changes
我试过 Core Data 的 refreshObject:mergeChanges:
方法,但没有成功。为什么 Watch 目标不反射(reflect)在同一托管对象上下文中对 Child
所做的更改?
更新
通过重写上面的代码,我发现通过两个不同的 NSFetchRequests 分别获取 NSManagedObjects,然后刷新对象会产生正确的值。这是更新后的代码:
// Parent fetch
let parentEntityDesc = NSEntityDescription.entityForName("Parent", inManagedObjectContext: WatchCoreDataProxy.sharedInstance.managedObjectContext!)
let parentRequest: NSFetchRequest = NSFetchRequest()
parentRequest.entity = parentEntityDesc
let parentPredicate = NSPredicate(format: "loadedOnWatch == 1")
parentRequest.predicate = parentPredicate
var parentError: NSError?
let array = WatchCoreDataProxy.sharedInstance.managedObjectContext!.executeFetchRequest(parentRequest, error: &parentError)! as NSArray
let parent: Parent = array[0] as! Parent
self.parentTitleLabel.setText(parent.name)
// Child fetch
let childEntityDesc = NSEntityDescription.entityForName("Child", inManagedObjectContext: WatchCoreDataProxy.sharedInstance.managedObjectContext!)
let childRequest: NSFetchRequest = NSFetchRequest()
childRequest.entity = childEntityDesc
let childPredicate = NSPredicate(format: "parent = %@", parent)
childRequest.predicate = childPredicate
let sort = NSSortDescriptor(key: "position", ascending: true)
childRequest.sortDescriptors = [sort]
var error: NSError?
self.childArray = WatchCoreDataProxy.sharedInstance.managedObjectContext!.executeFetchRequest(childRequest, error: &error)! as NSArray
let firstChild = self.childArray[0] as! Child
WatchCoreDataProxy.sharedInstance.managedObjectContext?.refreshObject(firstChild, mergeChanges: true)
let childTitle = firstChild.title
self.childTitleLabel.setText(childTitle)
那么,为什么以这种方式获取 NSManagedObjects 会产生正确的值,而不是依赖于父级的关系?
最佳答案
这取决于您的 NSManagedContext 的结构。 在 iPhone 应用程序中保存对“某些”NSManagedObject 上下文的更改是不够的,因为在 WatchKit 扩展中,实际上有不同的上下文(它是不同应用程序容器中完全不同的应用程序)。
因此您必须将更改更新到 Persistence Coordinator 中,它实际上将更改保存到应用程序组容器中的文件或 iCloud 中。
关于ios - NSManagedObject 更改未反射(reflect)在 WatchKit 扩展中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29905957/