@Published 属性包装器不适用于 ObservableObject 的子类 [英] @Published property wrapper not working on subclass of ObservableObject

查看:26
本文介绍了@Published 属性包装器不适用于 ObservableObject 的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个符合@ObservableObject 协议的类,并从它创建了一个子类,并使用它自己的变量和@Published 属性包装器来管理状态.

I have a class conforming to the @ObservableObject protocol and created a subclass from it with it's own variable with the @Published property wrapper to manage state.

似乎在使用子类时忽略了@published 属性包装器.有谁知道这是否是预期行为以及是否有解决方法?

It seems that the @published property wrapper is ignored when using a subclass. Does anyone know if this is expected behaviour and if there is a workaround?

我运行的是 iOS 13 Beta 8 和 xCode Beta 6.

I'm running iOS 13 Beta 8 and xCode Beta 6.

这是我所看到的一个例子.更新 MyTestObject 上的 TextField 时,Text 视图将正确更新为 aString 值.如果我更新 MyInheritedObjectTextField,则 anotherString 值不会在 Text 视图中更新.

Here is an example of what I'm seeing. When updating the TextField on MyTestObject the Text view is properly updated with the aString value. If I update the MyInheritedObjectTextField the anotherString value isn't updated in the Text view.

import SwiftUI

class MyTestObject: ObservableObject {
    @Published var aString: String = ""

}

class MyInheritedObject: MyTestObject {
    @Published var anotherString: String = ""
}

struct TestObserverWithSheet: View {
    @ObservedObject var myTestObject = MyInheritedObject()
    @ObservedObject var myInheritedObject = MyInheritedObject()

    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {
                TextField("Update aString", text: self.$myTestObject.aString)
                Text("Value of aString is: (self.myTestObject.aString)")

                TextField("Update anotherString", text: self.$myInheritedObject.anotherString)
                Text("Value of anotherString is: (self.myInheritedObject.anotherString)")
            }
        }
    }
}

推荐答案

终于找到了这个问题的解决方案/解决方法.如果您从子类中移除属性包装器,并在变量上调用基类 objectWillChange.send(),状态将正确更新.

Finally figured out a solution/workaround to this issue. If you remove the property wrapper from the subclass, and call the baseclass objectWillChange.send() on the variable the state is updated properly.

注意: 不要在子类上重新声明 let objectWillChange = PassthroughSubject() 因为这将再次导致状态无法正确更新.

NOTE: Do not redeclare let objectWillChange = PassthroughSubject<Void, Never>() on the subclass as that will again cause the state not to update properly.

我希望这会在未来的版本中得到修复,因为 objectWillChange.send() 是很多需要维护的样板.

I hope this is something that will be fixed in future releases as the objectWillChange.send() is a lot of boilerplate to maintain.

这是一个完整的示例:

    import SwiftUI

    class MyTestObject: ObservableObject {
        @Published var aString: String = ""

    }

    class MyInheritedObject: MyTestObject {
        // Using @Published doesn't work on a subclass
        // @Published var anotherString: String = ""

        // If you add the following to the subclass updating the state also doesn't work properly
        // let objectWillChange = PassthroughSubject<Void, Never>()

        // But if you update the value you want to maintain state 
        // of using the objectWillChange.send() method provided by the 
        // baseclass the state gets updated properly... Jaayy!
        var anotherString: String = "" {
            willSet { self.objectWillChange.send() }
        }
    }

    struct MyTestView: View {
        @ObservedObject var myTestObject = MyTestObject()
        @ObservedObject var myInheritedObject = MyInheritedObject()

        var body: some View {
            NavigationView {
                VStack(alignment: .leading) {
                    TextField("Update aString", text: self.$myTestObject.aString)
                    Text("Value of aString is: (self.myTestObject.aString)")

                    TextField("Update anotherString", text: self.$myInheritedObject.anotherString)
                    Text("Value of anotherString is: (self.myInheritedObject.anotherString)")
                }
            }
        }
    }

这篇关于@Published 属性包装器不适用于 ObservableObject 的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆