我有一个NSManagedObject Folder
的子类,其状态为Availability
@objc enum Availability: Int16 {
case unknown
case available
case unavailable
}
每当可用性更改时,文件夹都必须做一些额外的事情(例如删除相关文件)。所以我有
internalAvailability
保存在核心数据availability
`
extension Folder {
@NSManaged private var internalAvailability: Availability
}
extension Folder {
private func deleteFiles(...) {
...
}
@objc dynamic public var availability: Availability {
get {
return internalAvailability
}
set {
willChangeValue(forKey: "availability")
deleteFiles()
internalAvailability = newValue
didChangeValue(forKey: "availability")
}
}
}
我想使用Reactive,根据可用性更改导航项的标题,但是永远不会调用该信号!
```
let property = DynamicProperty<NSNumber>(object: folder, keyPath: "availability")
internalVariable = property // To have a reference of property
navigationItem.reactive.title <~ property.map { (stateNumber) -> String in
guard let a = Availability(rawValue: stateNumber.int16Value) else {
assertionFailure()
return ""
}
let prefix = a == .available ? "" : "(Nope) "
return "\(prefix)\(folder.name)"
}
我已将KVO合规性明确添加到该物业中,希望它能开始工作,但可惜没有结果。
编辑:如果我在
DynamicProperty
而不是internalAvailability
上创建availability
,那么一切都会顺利进行。 最佳答案
添加为答案,因为它已成为一项学习练习。希望其他人也将从中受益。
该应用程序使用多个ManagedObjectContext(moc)架构。 1个 private moc进行更改,还有1个主线程moc使用mergeChanges进行自身同步。
在上面的代码中,navigationItem
使用与main-moc一起保存的文件夹实例。 DynamicProperty正在侦听此主Moc的文件夹实例上的KVO更改。我们称它为主文件夹。进行更改时,我修改了private-moc上的文件夹实例。我们称其为 private 文件夹。
在修改专用文件夹并在private-moc上调用save
时,将广播名称NSManagedObjectContextDidSave
的通知。 main-moc使用mergeChanges进行自身同步。
mergeChanges更改主文件夹,但请注意,它将永远不会调用计算属性设置者availability
。它直接更改internalAvailability
。
因此,不会发布有关我们的计算属性的KVO通知。
TL; DR 对NSManagedObject子类进行KVO时,请使用存储的属性,而不要使用计算的属性。如果您有一个多对象(托管对象上下文)场景并使用mergeChanges进行同步,则在同步时不会为您的计算属性调用setter。
编辑(解决方案):模式keyPathsForValuesAffecting<KeyName>
KVO relevant documentation的添加方法
@objc class func keyPathsForValuesAffectingAvailability() -> Set<NSObject> {
return [#keyPath(Folder.internalAvailability) as NSObject]
}
关于ios - KVO无法用于NSManagedObject的自定义属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52643702/