我有一个核心数据模型,其中一个实体生成到类Task
中。我正在尝试从NSManagedObject
中获取要发送的联合发布者objectWillChange
(自动发送,无需手动操作),但不会成功。任务实体具有name
属性。
let task = Task(context: container.viewContext)
let taskSubscription = task.objectWillChange.sink(receiveValue: { _ in
print("Task changed")
})
task.name = "Foo" // WILL NOT trigger
如果我手动调用Send,订阅将起作用:
task.objectWillChange.send() // Will trigger
如果我将其替换为简单的ObservableObject
,它将按预期工作:
class DummyTask: ObservableObject {
@Published var name: String?
}
let dummy = DummyTask()
let dummySubscription = dummy.objectWillChange.sink(receiveValue: { _ in
print("Dummy changed")
})
dummy.name = "Foo" // Will trigger
dummy.objectWillChange.send() // Will trigger
NSManagedObject是否已被窃听?我应该如何观察常规实体对象的更改?我应该如何让SwiftUI看到它们?
这是使用Xcode11.0和iOS 13。
3条答案
按热度按时间cbjzeqam1#
我相信这是一个虫子。
NSManagedObject
符合ObservableObject
,但无法将任何属性标记为@Published
,这是没有意义的。在我们等待苹果纠正这一问题的同时,我发现了一个比@jesseSpencer建议的更干净的解决方案。背后的逻辑是相同的,通过添加
objectWillChange.send()
,但全局添加到willChangeValue(forKey key: String)
中,而不是添加到单个属性中。制片人:https://forums.developer.apple.com/thread/121897
jk9hmnmh2#
我的猜测是,这是一个错误。NSManagedObject与ObservableObject的一致性是在Beta 5中添加的,它还引入了其他重大变化,包括不推荐使用BindableObject(替换为ObservableObject)。
请参阅SwiftUI部分:https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes)
我遇到了同样的问题,尽管NSManagedObject符合ObservableObject,但它没有发出更改通知。这可能与需要用@NSManaged Package 的NSManagedObject属性有关,但不能与@发布的属性组合,而ObservableObject文档声明,默认情况下,ObservableObject将合成@发布属性更改的objectWillChange发布者。https://developer.apple.com/documentation/combine/observableobject
我首先尝试通过引导对
objectWillChange.send()
的调用来覆盖我的NSManagedObject子类中的键值方法,从而尝试解决这个问题,这只会导致不正确的行为。如果您需要在SwiftUI视图中更改许多相互依赖的属性,我使用的解决方案是最简单的,但不幸的是,可能是最笨重的。但是,到目前为止,它对我来说运行得很好,并保持了对SwiftUI的预期使用。
在SWIFT:
1.为您的实体创建NSManagedObject子类。
1.在该子类中,为您希望从SwiftUI视图更改的属性创建setter方法,并在该方法的开头添加对
objectWillChange.send()
的调用,该调用应如下所示:我只是建议这是一种临时的解决办法,因为这并不理想,希望很快就能解决。
我将在Feedback Assistant中提交一份错误报告,我建议遇到这个问题的其他人也这样做,这样我们就可以让Apple重新考虑这个问题!
编辑:关于@Anthony的回答的警告:虽然建议的方法确实有效,但请注意,当更改集合类型关系时,例如将对象添加到与NSManagedObject关联的数组中时,它将不起作用。
js81xvg63#
要观察
NSManagedObject
的变化,请查看:https://developer.apple.com/documentation/combine/performing-key-value-observing-with-combine。请注意,当您在
UICollectionViewListCell
或UITableViewCell
自定义类中使用该方法时,您应该覆盖prepareForReuse
方法并放入类似的代码: