I wanted to make a pitch for a deferred style of property wrapper, that will work with lazy properties only. The purpose is that you would be able to use another (non lazy) property as a dependency for the property wrapper.
Currently we can get around this by using a class for the property wrapper, then after initialisation setting the dependency on the property wrapper. For example:
@propertyWrapper
class Foo<Baz, Bar, Value> {
let baz: Baz
var bar: Bar?
var wrappedValue: Value? {
get { bar?.get(baz) }
set { bar?.set(newValue, for: baz)
}
init(baz: Baz) {
self.baz = baz
}
func configure(bar: Bar) {
self.bar = bar
}
}
This, however means after initialisation you have to run through all @Foo
properties to then configure bar
.
class Item {
let bar: Bar
@Foo(baz: Baz())
var property: Value
init(bar: Bar) {
self.bar = bar
_property.configure(bar: bar)
}
}
Proposed Solution
Add a deferredPropertyWrapper which allows the usage of self
in the initialiser of the property wrapper. Make it required that the property is marked with lazy
so that the user is aware that the property wrapper is deferred until after initialisation.
@deferredPropertyWrapper
struct Foo<Baz, Bar, Value>
let baz: Baz
let bar: Bar
var wrappedValue: Value {
get { bar.get(baz) }
set { bar.set(baz) }
}
Then when you want to use the property wrapper you can use another non lazy property of self
class Item {
let bar: Bar
@Foo(baz: Baz(), bar: bar)
lazy var property: Value
}