ReactiveSwift:使用 MutableProperty 观察托管对象的变化
ReactiveSwift: Observe Managed Object changes with MutableProperty
我的项目有 CoreData
个数据库,其中有 1 个根上下文和多个子上下文。
我有一个包含项目 (NSManagedObject
) 的 ViewModel
。当我更改项目中的某些内容时,会在根上下文中进行持久化,然后自动合并到所有子上下文中。
我想用 ReactiveSwift
信号/属性替换 NSFetchedResultsController
,以观察项目对象的变化。
视图模型:
var itemProperty: MutableProperty<Item> = MutableProperty(contextItem)
ViewController:
self.viewModel.itemProperty.signal.observeValues{ (item: Item) in
let newName = item.name
print("name: \(newName!)"
}
在我在别处更改项目名称后,更改会传播到 ViewModel
子上下文(NSFetchedResultsController
会收到通知),但信号永远不会推送新的 item
事件。
可能是因为 NSManagedObject
引用永远不会改变?我知道我可以使用 producer(forKeyPath: "propertyKeyPath" )
观察对象中特定属性的变化,但我不想只观察项目的一个特定 属性,我想观察所有变化。
有没有办法观察所有对象属性的任何变化??
您可以观察 NSManagedObjectContextObjectsDidChange
。这可能有点矫枉过正,因为它会在 any 对象发生 any 更改时发送通知。但我已经使用它而没有任何明显的性能影响。这是 Apple documentation.
NSManagedObjectContextObjectsDidChange
的主要缺点是它不会为您提供更改后的键或值。如果您需要,请意识到在所有属性上创建观察者可能并不像您想象的那么繁重。它可以在一个循环中完成,遍历 NSEntityDescription.properties
或 its documentation 底部列出的其他四个类似属性之一。
很明显,经过一些研究后,我发现 ReactiveCocoa 还没有做好使用 Core Data 的准备。仅 ReactiveCocoa/ReactiveSwift.
无法接收 NSManagedObject 更新
一个选项可以是使用来自 NSFetchedResultsController 的每次更新来更新 ItemProperty,并在 属性 的关联信号上触发一个新事件:
var entityProperty: MutableProperty<MyEntity>
override func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
{
entityProperty.value = anObject as! MyEntity
}
另一种选择是获取我实体中特定属性更新的信号:
var myEntity: MyEntity
// ReactiveObjectiveC
myEntity.rac_values(forKeyPath: "name", observer: self)
// ReactiveSwift
myEntity.reactive.signal(forKeyPath: "name")
我的项目有 CoreData
个数据库,其中有 1 个根上下文和多个子上下文。
我有一个包含项目 (NSManagedObject
) 的 ViewModel
。当我更改项目中的某些内容时,会在根上下文中进行持久化,然后自动合并到所有子上下文中。
我想用 ReactiveSwift
信号/属性替换 NSFetchedResultsController
,以观察项目对象的变化。
视图模型:
var itemProperty: MutableProperty<Item> = MutableProperty(contextItem)
ViewController:
self.viewModel.itemProperty.signal.observeValues{ (item: Item) in
let newName = item.name
print("name: \(newName!)"
}
在我在别处更改项目名称后,更改会传播到 ViewModel
子上下文(NSFetchedResultsController
会收到通知),但信号永远不会推送新的 item
事件。
可能是因为 NSManagedObject
引用永远不会改变?我知道我可以使用 producer(forKeyPath: "propertyKeyPath" )
观察对象中特定属性的变化,但我不想只观察项目的一个特定 属性,我想观察所有变化。
有没有办法观察所有对象属性的任何变化??
您可以观察 NSManagedObjectContextObjectsDidChange
。这可能有点矫枉过正,因为它会在 any 对象发生 any 更改时发送通知。但我已经使用它而没有任何明显的性能影响。这是 Apple documentation.
NSManagedObjectContextObjectsDidChange
的主要缺点是它不会为您提供更改后的键或值。如果您需要,请意识到在所有属性上创建观察者可能并不像您想象的那么繁重。它可以在一个循环中完成,遍历 NSEntityDescription.properties
或 its documentation 底部列出的其他四个类似属性之一。
很明显,经过一些研究后,我发现 ReactiveCocoa 还没有做好使用 Core Data 的准备。仅 ReactiveCocoa/ReactiveSwift.
无法接收 NSManagedObject 更新一个选项可以是使用来自 NSFetchedResultsController 的每次更新来更新 ItemProperty,并在 属性 的关联信号上触发一个新事件:
var entityProperty: MutableProperty<MyEntity>
override func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
{
entityProperty.value = anObject as! MyEntity
}
另一种选择是获取我实体中特定属性更新的信号:
var myEntity: MyEntity
// ReactiveObjectiveC
myEntity.rac_values(forKeyPath: "name", observer: self)
// ReactiveSwift
myEntity.reactive.signal(forKeyPath: "name")