微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将自定义属性包装器与 @Published 结合使用 最小代码示例

如何解决将自定义属性包装器与 @Published 结合使用 最小代码示例

我希望将自定义属性包装器应用于已经包装在 @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)标记的一样

真正的问题是,我如何观察属性/状态更新变化?

  1. 使用@Published 包装器,自动处理状态更新

  2. 通过实施手动跟踪状态更新

    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 包装器完全正常工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。