这是模型数据

class A {
    var p: Int = 1

    func update() {
        self.p = self.p + 1
    }
}


@Observable
class BStore: A {
    // nothing
}

这是一个观点

struct ContentView: View {
    @State private var bStore = BStore()

    var body: some View {
        CountView()
            .environment(bStore)
    }
}

struct CountView: View {
    @Environment(BStore.self) private var bStore

    var body: some View {
        Text("count: \(bStore.p)")
            .onTapGesture(perform: {
                bStore.update()
            })
    }
}

bStore.p正确更改,但不更新视图;如果class A添加@Observable,则视图将正常更新

我有两个问题:

  1. 在目前的设计和class A不使用@Observable的情况下,如何使视图正确更新?如果没有,那么如何设计呢?前提是class A不能使用@Observable,因为class A不仅服务于视图,@Observable class BStore相当于class A的代理只服务于视图

  2. bStore继承class A并具有其所有属性和方法,并使用@Observable,但是为什么没有跟踪bStore的父类属性的更改,从而导致视图不更改?

推荐答案

@Observablemacro.当它展开时,它会找到类中存储的所有属性,并 for each 属性添加特殊的getter和setter.

除了返回和设置属性值之外,这些getter和setter还通知ObservationRegistrar(也是由宏生成的)这些属性被访问/修改.使用这一点,SwiftUI可以找到视图的依赖项并正确跟踪更改.

如果将@Observable应用于一个子类,则那里没有声明任何存储属性,因此@Observable不会生成任何通知ObservationRegistrar的getter/setter.宏只对代码的textual个内容进行操作--它们不能转到超类并判断那里有哪些存储的属性.

如果您真的想要BStore个可观察的,而不是A,您将需要重写p,并添加@Observablewould have generated的getter和setter.

@Observable
class BStore: A {
    override var p: Int {
        get {
            access(keyPath: \.p)
            return super.p
        }
        set {
            withMutation(keyPath: \.p) {
                super.p = newValue
            }
        }
    }
}

您需要为要观察的每个属性执行此操作.

Ios相关问答推荐

如何加密字符串使用AES. GCM在Dart和解密相同的Swift?

UIBezierPath包含:方法不检测到厚度大于1像素的线上的touch

Jenkins node 无法运行fastlane命令-未找到命令

SWIFT-仅解码感兴趣的元素

如何使用 SwiftData 从列表中删除子项目?

无法向委托发送数据

如何删除点击时按钮的不透明动画?

如何在 Flutter 应用程序中测试来自 App/Play Store 的移动深层链接?

每次我路由到应用程序的主屏幕时,都无法使组合订阅正常工作

动画文本位置

从iOS键盘输入时Flutter TextField输入消失

如何让替换视图淡入旧视图而不是交叉淡入淡出?

渲染的海边重定向在物理 iOS 设备上不起作用

UIViewControllerRepresentable 在 Xcode 14 iOS 16 上崩溃

迁移到 UIKit 生命周期的应用程序不会调用 SceneDelegate

NSFetchedResultsController 由字符串的第一个字母创建的部分

ARKit vs. ARCore vs. Vuforia vs. D'Fusion Mobile vs. Layar SDK

通过 segue 传递数据

在 React Native 中保存敏感数据

正确使用 Alamofire 的 URLRequestConvertible