File tree Expand file tree Collapse file tree 2 files changed +20
-14
lines changed
stdlib/public/Observation/Sources/Observation Expand file tree Collapse file tree 2 files changed +20
-14
lines changed Original file line number Diff line number Diff line change @@ -110,20 +110,27 @@ public struct ObservationRegistrar: Sendable {
110
110
}
111
111
}
112
112
113
- internal mutating func deinitialize( ) -> [ @Sendable ( ) -> Void ] {
114
- var trackers = [ @Sendable ( ) -> Void ] ( )
113
+ internal mutating func deinitialize( ) -> ( @Sendable ( ) -> Void ) ? {
114
+ func extractSelf< T> ( _ ty: T . Type ) -> AnyKeyPath {
115
+ return \T . self
116
+ }
117
+
118
+ var tracker : ( @Sendable ( ) -> Void ) ?
115
119
for (keyPath, ids) in lookups {
116
120
for id in ids {
117
- if let tracker = observations [ id] ? . willSetTracker {
118
- trackers. append ( {
119
- tracker ( keyPath)
120
- } )
121
+ if let found = observations [ id] ? . willSetTracker {
122
+ // convert the keyPath into its \Self.self version
123
+ let selfKp = _openExistential ( type ( of: keyPath) . rootType, do: extractSelf)
124
+ found = {
125
+ tracker ( selfKp)
126
+ }
127
+ break
121
128
}
122
129
}
123
130
}
124
131
observations. removeAll ( )
125
132
lookups. removeAll ( )
126
- return trackers
133
+ return tracker
127
134
}
128
135
129
136
internal mutating func willSet( keyPath: AnyKeyPath ) -> [ @Sendable ( AnyKeyPath ) -> Void ] {
@@ -169,10 +176,7 @@ public struct ObservationRegistrar: Sendable {
169
176
}
170
177
171
178
internal func deinitialize( ) {
172
- let tracking = state. withCriticalRegion { $0. deinitialize ( ) }
173
- for action in tracking {
174
- action ( )
175
- }
179
+ state. withCriticalRegion { $0. deinitialize ( ) } ? ( )
176
180
}
177
181
178
182
internal func willSet< Subject: Observable , Member> (
Original file line number Diff line number Diff line change @@ -290,6 +290,7 @@ final class CowTest {
290
290
@Observable
291
291
final class DeinitTriggeredObserver {
292
292
var property : Int = 3
293
+ var property2 : Int = 4
293
294
let deinitTrigger : ( ) -> Void
294
295
295
296
init ( _ deinitTrigger: @escaping ( ) -> Void ) {
@@ -528,17 +529,18 @@ struct Validator {
528
529
529
530
suite. test ( " weak container observation " ) {
530
531
let changed = CapturedState ( state: false )
531
- let deinitialized = CapturedState ( state: false )
532
+ let deinitialized = CapturedState ( state: 0 )
532
533
var test = DeinitTriggeredObserver {
533
- deinitialized. state = true
534
+ deinitialized. state += 1
534
535
}
535
536
withObservationTracking { [ weak test] in
536
537
_blackHole ( test? . property)
538
+ _blackHole ( test? . property2)
537
539
} onChange: {
538
540
changed. state = true
539
541
}
540
542
test = DeinitTriggeredObserver { }
541
- expectEqual ( deinitialized. state, true )
543
+ expectEqual ( deinitialized. state, 1 ) // ensure only one invocation is done per deinitialization
542
544
expectEqual ( changed. state, true )
543
545
}
544
546
You can’t perform that action at this time.
0 commit comments