From a17e303bf139cd361f70d60fd74cfd23e8969652 Mon Sep 17 00:00:00 2001 From: Philippe Hausler Date: Fri, 1 Aug 2025 13:58:10 -0700 Subject: [PATCH] Revert "[Observation] Ensure deinitialized Observable types don't leave active observations in memory (#82752)" This reverts commit a349e64039eabb6f7639f9c25870fc9dabd9984a. --- .../Observation/ObservationRegistrar.swift | 26 +++------------ test/stdlib/Observation/Observable.swift | 33 ------------------- 2 files changed, 4 insertions(+), 55 deletions(-) diff --git a/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift b/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift index 58fd1ff827bf4..3c356381bee63 100644 --- a/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift +++ b/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift @@ -110,27 +110,9 @@ public struct ObservationRegistrar: Sendable { } } - internal mutating func deinitialize() -> (@Sendable () -> Void)? { - func extractSelf(_ ty: T.Type) -> AnyKeyPath { - return \T.self - } - - var tracker: (@Sendable () -> Void)? - lookupIteration: for (keyPath, ids) in lookups { - for id in ids { - if let found = observations[id]?.willSetTracker { - // convert the keyPath into its \Self.self version - let selfKp = _openExistential(type(of: keyPath).rootType, do: extractSelf) - tracker = { - found(selfKp) - } - break lookupIteration - } - } - } + internal mutating func cancelAll() { observations.removeAll() lookups.removeAll() - return tracker } internal mutating func willSet(keyPath: AnyKeyPath) -> [@Sendable (AnyKeyPath) -> Void] { @@ -175,8 +157,8 @@ public struct ObservationRegistrar: Sendable { state.withCriticalRegion { $0.cancel(id) } } - internal func deinitialize() { - state.withCriticalRegion { $0.deinitialize() }?() + internal func cancelAll() { + state.withCriticalRegion { $0.cancelAll() } } internal func willSet( @@ -207,7 +189,7 @@ public struct ObservationRegistrar: Sendable { } deinit { - context.deinitialize() + context.cancelAll() } } diff --git a/test/stdlib/Observation/Observable.swift b/test/stdlib/Observation/Observable.swift index 81b3f7bf1cbc6..9fa23325805fc 100644 --- a/test/stdlib/Observation/Observable.swift +++ b/test/stdlib/Observation/Observable.swift @@ -287,22 +287,6 @@ final class CowTest { var container = CowContainer() } -@Observable -final class DeinitTriggeredObserver { - var property: Int = 3 - var property2: Int = 4 - let deinitTrigger: () -> Void - - init(_ deinitTrigger: @escaping () -> Void) { - self.deinitTrigger = deinitTrigger - } - - deinit { - deinitTrigger() - } -} - - @main struct Validator { @MainActor @@ -527,23 +511,6 @@ struct Validator { expectEqual(subject.container.id, startId) } - suite.test("weak container observation") { - let changed = CapturedState(state: false) - let deinitialized = CapturedState(state: 0) - var test = DeinitTriggeredObserver { - deinitialized.state += 1 - } - withObservationTracking { [weak test] in - _blackHole(test?.property) - _blackHole(test?.property2) - } onChange: { - changed.state = true - } - test = DeinitTriggeredObserver { } - expectEqual(deinitialized.state, 1) // ensure only one invocation is done per deinitialization - expectEqual(changed.state, true) - } - runAllTests() } }