如何在@Observable标注的类中使用@Resettable属性包装器?
如何同时使用@Resettable属性包装器和@Observable宏?
你遇到的错误确实是因为@Observable宏会将类中的存储属性转换为带合成访问器的计算属性,而属性包装器无法直接应用在计算属性上。下面提供几种可行的解决方案:
方案一:修改@Resettable包装器兼容@Observable
让自定义属性包装器本身遵循Observable协议,内部用@ObservationState管理值的存储,这样@Observable宏就能正确识别并处理它,不会触发冲突:
@propertyWrapper struct Resettable<T>: Observable { @ObservationState private var wrappedValue: T let defaultValue: T init(wrappedValue: T) { self.defaultValue = wrappedValue self._wrappedValue = ObservationState(wrappedValue) } var wrappedValue: T { get { _wrappedValue.wrappedValue } set { _wrappedValue.wrappedValue = newValue } } var projectedValue: T { defaultValue } }
在@Observable类中使用方式保持不变:
@Observable final class Person { @Resettable var name = "John Doe" func revertName() { name = $name } }
这种方案适合有大量需要重置的属性的场景,能复用重置逻辑,同时保留@Observable的观察能力。
方案二:手动维护默认值(无属性包装器)
如果需要重置的属性不多,可以直接在类中存储默认值,去掉属性包装器,手动实现重置逻辑:
@Observable final class GameScene: SKScene { // 存储默认值 private let defaultRunningSpeed: CGFloat = 1.0 // 可观察的属性 var runningSpeed: CGFloat = 1.0 func resetRunningSpeed() { runningSpeed = defaultRunningSpeed } }
这种方式简单直接,完全避免了属性包装器和@Observable的冲突,适合属性数量较少的场景。
方案三:手动实现属性访问器
把重置逻辑嵌入到属性的自定义getter/setter中,自己控制存储,同样能兼容@Observable:
@Observable final class Person { private let defaultName = "John Doe" private var _name = "John Doe" var name: String { get { _name } set { _name = newValue } } func revertName() { name = defaultName } }
这种方式完全绕过属性包装器,灵活性高,适合需要对属性访问做额外自定义逻辑的场景。
内容的提问来源于stack exchange,提问作者rayaantaneja
相关产品推荐
相关产品推荐

