我正在尝试使用 Swift 5.1 属性包装器,但每次我认为我有一个很酷的用例时,我最终都会遇到无法在 View Model 的初始化程序中使用它们的问题。
举这个极其简单的例子。
class NoProblem {
var foo = "ABC"
let upperCased: String
init(dependencies: AppDependencies) {
self.upperCased = foo.uppercased()
}
}
@propertyWrapper
struct Box<Value> {
private var box: Value
init(wrappedValue: Value) {
box = wrappedValue
}
var wrappedValue: Value {
get { box }
set { box = newValue }
}
}
class OhNoes {
@Box var foo = "ABC"
let upperCased: String
init(dependencies: AppDependencies) {
self.upperCased = foo.uppercased()
}
}
在NoProblem
中,一切都按预期工作。但是在OhNoes
我得到这个错误:'self' used in property access 'foo' before all stored properties are initialized
。
当然这是一个非常简化的例子,但是我在做同样的问题时遇到了同样的问题@Property
为可观察属性或本文@Injected
中的包装器等进行包装时,我遇到了同样的问题。
不,可悲的是,让它成为一个非专业的财产也行不通:Property 'foo' with a wrapper cannot also be lazy
.
这在 SwiftUI 中也是一个相当大的问题,请看这个例子:
class AppStore: ObservableObject {
let foo = "foo"
}
struct ContentView: View {
@EnvironmentObject private var store: AppStore
private let foo: String
init() {
foo = store.foo // error: 'self' used before all stored properties are initialized
}
var body: some View {
Text("Hello world")
}
}