Property wrappers are stored properties, so I expected didSet/willSet to work as usual, but they are ignored actually. Here is a short example:
@propertyWrapper
struct MutableWrapper<Value> {
var wrappedValue: Value
var projectedValue: Self {
get { self }
set { self = newValue }
}
mutating func mutate() {
// any mutations here
}
}
struct TestStruct {
@MutableWrapper var value = 0 {
didSet { print("mutated") }
}
}
func testDidSet() {
var testStruct = TestStruct()
testStruct.$value.mutate() // prints nothing
testStruct.value = 1 // prints nothing
}
All sets are mutating; I don't use classes, so it's definitely a bug. Does anybody know something about it?
I really need to observe mutations of my wrapper itself. I didn't expect any problems here, especially since the compiler allowed me to write didSet under the wrapped value.
Ray_Fix
(Ray Fix)
2
For me (Swift 5.10 Xcode 15.3), using XCTestCase and your exact code:
testStruct.value = 1 // prints "mutated"
I don't know how to observe mutations on the wrapper other than maybe creating a custom type for it.
import XCTest
extension Int {
mutating func mutate() {
self = 42
}
}
@propertyWrapper
struct MutableWrapper<Value: BinaryInteger> {
var wrappedValue: Value
var projectedValue: Int = 0 {
didSet {
print("Mutated")
}
}
}
struct TestStruct {
@MutableWrapper var value = 0 {
didSet { print("mutated") }
}
}
final class ActorDemoTests: XCTestCase {
func testDidSet() {
var testStruct = TestStruct()
testStruct.$value.mutate() // prints Mutated
testStruct.value = 1 // prints mutated
}
}
Sorry if that isn't much help, though.
1 Like