whi*_*ler 9 core-data swift swiftui combine
我有一个核心数据模型,其中一个实体生成到 class 中Task。我正在尝试objectWillChange从NSManagedObject发送(自动,无需手动工作)中获取合并发布者,但它不会。任务实体有一个name属性。
let task = Task(context: container.viewContext)
let taskSubscription = task.objectWillChange.sink(receiveValue: { _ in
print("Task changed")
})
task.name = "Foo" // WILL NOT trigger
Run Code Online (Sandbox Code Playgroud)
如果我手动调用发送,订阅将起作用:
task.objectWillChange.send() // Will trigger
Run Code Online (Sandbox Code Playgroud)
如果我用一个 simple 替换ObservableObject它,它将按预期工作:
class DummyTask: ObservableObject {
@Published var name: String?
}
Run Code Online (Sandbox Code Playgroud)
let dummy = DummyTask()
let dummySubscription = dummy.objectWillChange.sink(receiveValue: { _ in
print("Dummy changed")
})
dummy.name = "Foo" // Will trigger
dummy.objectWillChange.send() // Will trigger
Run Code Online (Sandbox Code Playgroud)
NSManagedObject 被窃听了吗?我应该如何观察通用实体对象的变化?我应该如何让 SwiftUI 看到它们?
这是使用 Xcode 11.0 和 iOS 13。
我相信这是一个错误。没有必要NSManagedObject符合ObservableObject但无法将任何属性标记为@Published。
在我们等待 Apple 纠正此问题的同时,我遇到了比 @jesseSpencer 建议的更简洁的解决方案。背后的逻辑是相同的,通过添加 a objectWillChange.send(),但全局添加到willChangeValue(forKey key: String)而不是添加到单个属性。
override public func willChangeValue(forKey key: String) {
super.willChangeValue(forKey: key)
self.objectWillChange.send()
}
Run Code Online (Sandbox Code Playgroud)
学分:https : //forums.developer.apple.com/thread/121897
我的猜测是这是一个错误。NSManagedObject 与 ObservableObject 的一致性是在 beta 5 中添加的,它还引入了其他重大更改,包括弃用 BindableObject(由 ObservableObject 替换)。
请参阅 SwiftUI 部分:https : //developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes)
我遇到了同样的问题,尽管 NSManagedObject 符合 ObservableObject,但它没有发出更改通知。这可能与需要用 @NSManaged 包装的 NSManagedObject 属性有关,@NSManaged 不能与 @Published 结合使用,而 ObservableObject 文档指出,默认情况下,ObservableObject 将为 @Published 属性更改合成 objectWillChange 发布者。https://developer.apple.com/documentation/combine/observableobject
我首先尝试通过引导调用对objectWillChange.send()我的 NSManagedObject 子类中的键值方法的覆盖调用来解决这个问题,这只会导致错误的行为。
如果您需要更改 SwiftUI 视图中的许多相互依赖的属性,我采用的解决方案是最简单但不幸的是可能是最笨重的。但是,到目前为止,它对我来说运行良好,并按预期保持使用 SwiftUI。
在斯威夫特:
在该子类中,为您希望从 SwiftUI 视图更改的属性创建 setter 方法,并在该方法的开头添加对 的调用objectWillChange.send(),该调用应如下所示:
func setTitle(_ text: String) {
objectWillChange.send()
self.title = text
}
Run Code Online (Sandbox Code Playgroud)我只建议这是一个临时的解决方法,因为它并不理想,希望很快会得到解决。
我将在 FeedbackAssistant 中提交错误报告,并建议遇到此问题的其他任何人也这样做,以便我们可以让 Apple 再看看这个!
编辑:关于@Anthony 答案的警告:虽然建议的方法确实有效,但请注意它在更改集合类型关系时将不起作用,即将对象添加到与 NSManagedObject 关联的数组中。
| 归档时间: |
|
| 查看次数: |
2557 次 |
| 最近记录: |