ReactiveSwift:使用 MutableProperty 观察托管对象的变化

Posted

技术标签:

【中文标题】ReactiveSwift:使用 MutableProperty 观察托管对象的变化【英文标题】:ReactiveSwift: Observe Managed Object changes with MutableProperty 【发布时间】:2019-04-29 19:50:38 【问题描述】:

我的项目有 CoreData 数据库,其中包含 1 个根上下文和多个子上下文。 我有一个 ViewModel,其中包含一个项目 (NSManagedObject)。当我在 Item 中更改某些内容时,会在根上下文中进行持久化,然后自动合并到所有子上下文中。

我想将NSFetchedResultsController 替换为ReactiveSwift 信号/属性,以观察项目对象的变化。

视图模型:

var itemProperty: MutableProperty<Item> = MutableProperty(contextItem)

视图控制器:

self.viewModel.itemProperty.signal.observeValues (item: Item) in
     let newName = item.name
     print("name: \(newName!)" 
 

在我在其他地方更改项目名称后,更改会传播到 ViewModel 子上下文(NSFetchedResultsController 会收到通知),但信号永远不会推送新的 item 事件。

也许是因为NSManagedObject 引用永远不会改变?我知道我可以使用producer(forKeyPath: "propertyKeyPath" ) 观察对象中特定属性的变化,但我不想只观察项目的一个特定属性,我想观察所有变化。

有没有办法观察所有对象属性的任何变化??

【问题讨论】:

【参考方案1】:

你可以观察NSManagedObjectContextObjectsDidChange。这可能有些矫枉过正,因为它会在 any 对象发生 any 更改时发送通知。但是我使用它没有任何明显的性能影响。这是Apple documentation。

NSManagedObjectContextObjectsDidChange 的主要缺点是它不会为您提供更改的键或值。如果您需要,请意识到在所有属性上创建观察者可能并不像您想象的那么繁重。它可以在一个循环中完成,遍历NSEntityDescription.properties 或its documentation 底部列出的其他四个类似属性之一。

【讨论】:

是的!我知道我可以使用NSManagedObejctContext,但我想用 ReactiveSwift 完全观察变化。因为如果我使用 NSManagedObjectContextObjectsDidChange 我只会使用 ReactiveSwift 信号来替换委托模式。【参考方案2】:

显然,经过一番研究后,我发现 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")

【讨论】:

以上是关于ReactiveSwift:使用 MutableProperty 观察托管对象的变化的主要内容,如果未能解决你的问题,请参考以下文章

reactiveswift 空信号用于干吗

ReactiveSwift框架

ReactiveSwift源码解析 Event与Observer代码实现

ReactiveSwift源码解析 Atomic的代码实现以及其中的Defer延迟Posix互斥锁递归锁

iOS 项目从 ReactiveSwift 迁移到 openCombine

从 ReactiveSwift 迁移到 Combine