Skip to content

Commit 2c514fb

Browse files
committed
wip
1 parent 7e3cd58 commit 2c514fb

File tree

1 file changed

+24
-31
lines changed

1 file changed

+24
-31
lines changed

Sources/ComposableArchitecture/Store.swift

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,6 @@ import SwiftUI
9393
/// package when targeting iOS <17) by applying the ``ObservableState()`` macro to your feature's
9494
/// state.
9595

96-
97-
@MainActor
98-
protocol _Store: AnyObject {
99-
var allChildren: [AnyObject] { get }
100-
func removeChild(_ store: AnyObject)
101-
}
102-
103-
10496
@dynamicMemberLookup
10597
#if swift(<5.10)
10698
@MainActor(unsafe)
@@ -109,16 +101,11 @@ protocol _Store: AnyObject {
109101
#endif
110102
public final class Store<State, Action>: _Store {
111103
var children: [ScopeID<State, Action>: AnyObject] = [:]
104+
private weak var parent: (any _Store)?
105+
private let scopeID: AnyHashable?
112106

113-
var allChildren: [AnyObject] {
114-
Array(children.values)
115-
}
116-
func removeChild(_ store: AnyObject) {
117-
for (key, child) in children {
118-
guard child === store
119-
else { continue }
120-
children.removeValue(forKey: key)
121-
}
107+
func removeChild(scopeID: AnyHashable) {
108+
children[scopeID as! ScopeID<State, Action>] = nil
122109
}
123110

124111
let core: any Core<State, Action>
@@ -159,6 +146,7 @@ public final class Store<State, Action>: _Store {
159146

160147
init() {
161148
self.core = InvalidCore()
149+
self.scopeID = nil
162150
}
163151

164152
deinit {
@@ -286,7 +274,7 @@ public final class Store<State, Action>: _Store {
286274
let id,
287275
let child = children[id] as? Store<ChildState, ChildAction>
288276
else {
289-
let child = Store<ChildState, ChildAction>(core: childCore(), parent: self)
277+
let child = Store<ChildState, ChildAction>(core: childCore(), scopeID: id, parent: self)
290278
if core.canStoreCacheChildren, let id {
291279
children[id] = child
292280
}
@@ -333,28 +321,24 @@ public final class Store<State, Action>: _Store {
333321
core.send(action)
334322
}
335323

336-
private weak var parent: (any _Store)?
337-
338-
private init(core: some Core<State, Action>, parent: (any _Store)?) {
339-
defer { Logger.shared.log("\(storeTypeName(of: self)).init") }
324+
private init(core: some Core<State, Action>, scopeID: AnyHashable?, parent: (any _Store)?) {
325+
defer { Logger.shared.log( "\(storeTypeName(of: self)).init") }
340326
self.core = core
341327
self.parent = parent
328+
self.scopeID = scopeID
342329

343330
if let stateType = State.self as? any ObservableState.Type {
344331
func subscribeToDidSet<T: ObservableState>(_ type: T.Type) -> AnyCancellable {
345332
return core.didSet
346-
.prefix { [weak self] _ in
347-
guard let self else { return false }
348-
let isInvalid = self.core.isInvalid
349-
if isInvalid {
350-
self.parent?.removeChild(self)
351-
}
352-
return !isInvalid
353-
}
333+
.prefix { [weak self] _ in self?.core.isInvalid == false }
354334
.compactMap { [weak self] in (self?.currentState as? T)?._$id }
355335
.removeDuplicates()
356336
.dropFirst()
357337
.sink { [weak self] _ in
338+
guard let scopeID = self?.scopeID
339+
else { return }
340+
parent?.removeChild(scopeID: scopeID)
341+
} receiveValue: { [weak self] _ in
358342
guard let self else { return }
359343
self._$observationRegistrar.withMutation(of: self, keyPath: \.currentState) {}
360344
}
@@ -367,7 +351,11 @@ public final class Store<State, Action>: _Store {
367351
initialState: R.State,
368352
reducer: R
369353
) {
370-
self.init(core: RootCore(initialState: initialState, reducer: reducer), parent: nil)
354+
self.init(
355+
core: RootCore(initialState: initialState, reducer: reducer),
356+
scopeID: nil,
357+
parent: nil
358+
)
371359
}
372360

373361
/// A publisher that emits when state changes.
@@ -595,3 +583,8 @@ let _isStorePerceptionCheckingEnabled: Bool = {
595583
@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *)
596584
extension Store: Observable {}
597585
#endif
586+
587+
@MainActor
588+
private protocol _Store: AnyObject {
589+
func removeChild(scopeID: AnyHashable)
590+
}

0 commit comments

Comments
 (0)