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

查看:102
本文介绍了@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时,将使用aString值正确更新文本"视图.如果我更新MyInheritedObject TextField,则Text视图中的anotherString值不会更新.

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<Void, Never>(),因为这将再次导致状态无法正确更新.

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.

这是一个可以正常工作的示例:

Here is a fully working example:

    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天全站免登陆