问题描述
我希望将自定义属性包装器应用于已经包装在 @Published
中的变量,像
一样嵌套它们
(A) @Custom @Published var myVar
或
(B) @Published @Custom var myVar
(注意包装器的应用顺序)。
在 (A) 的情况下,我得到错误
'wrappedValue' is unavailable: @Published is only available on properties of classes
对于(B)
error: key path value type 'Int' cannot be converted to contextual type 'Updating<Int>'
两者都没有特别的帮助。任何想法如何使它工作?
最小代码示例
import Combine
class A {
@Updating @Published var b: Int
init(b: Int) {
self.b = b
}
}
@propertyWrapper struct Updating<T> {
var wrappedValue: T {
didSet {
print("Update: \(wrappedValue)")
}
}
}
let a = A(b: 1)
let cancellable = a.$b.sink {
print("Published: \($0)")
}
a.b = 2
// Expected output:
// ==> Published: 1
// ==> Published: 2
// ==> Update: 2
解决方法
您提供的任何选项都不能用于使自定义属性包装器的行为与用@Published(A 和 B)标记的一样
真正的问题是,我如何观察属性/状态更新变化?
-
使用@Published 包装器,自动处理状态更新
-
通过实施手动跟踪状态更新
willSet {objectWillChange.send()}
考虑到选项 1 无法工作,因为您无法应用 2 个属性包装器, 您可以进行手动状态更新跟踪。 为了实现这一点,您需要使您的类符合 ObservableObject 协议。
class A: ObservableObject {
@Updating var b: Int{
willSet {objectWillChange.send()}
}
init(b: Int) {
self.b = b
}
}
您的视图现在可以在 var b 更改时刷新,同时您的 @Updating 包装器完全正常工作。