I thought it didn't work, but my experiment shows it works fine.
@Observable
final class Foo {
var x: Int = 0 {
didSet {
print("didSet was called")
}
}
}
func test() {
var foo = Foo()
withObservationTracking {
let _ = foo.x
} onChange: {
print("x was changed")
}
foo.x = 1
}
test()
// Output:
// x was changed
// didSet was called
So I expand macro in Xcode and find the following
@ObservationTracked var x: Int = 0 {
didSet {
print("didSet was called")
}
}
is expanded to:
var x: Int = 0 {@storageRestrictions(initializes: _x)
init(initialValue) {
_x = initialValue
}
get {
access(keyPath: \.x)
return _x
}
set {
withMutation(keyPath: \.x) {
_x = newValue
}
}
didSet {
print("didSet was called")
}
}
I knew didSet
couldn't be used with computed variable before, so I thought this was a new feature. However, when I try to reproduce the behavior with my own code, it can't compile.
struct Bar {
var _x: Int = 0
var x: Int {
@storageRestrictions(initializes: _x)
init(initialValue) {
_x = initialValue
}
get {
return _x
}
set {
_x = newValue
}
// Compiler error: 'didSet' cannot be provided together with an init accessor
didSet {
print("didSet was called")
}
}
}
Any idea why it works in macro expanded code but not in my own code? Thanks.