Skip to content

Commit b6ea5b0

Browse files
tgrapperonmluisbrown
authored andcommitted
Update ObservableObjectPublisher's instances in _StateObject (#1341)
(cherry picked from commit 247458621dff85f78e2a25097f4048b587dc25b8)
1 parent c89475a commit b6ea5b0

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

Sources/ComposableArchitecture/Internal/_StateObject.swift

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,40 @@ import SwiftUI
33

44
@propertyWrapper
55
struct _StateObject<Object: ObservableObject>: DynamicProperty {
6-
private final class ObjectWillChange: ObservableObject {
7-
// Manually defining this property allows to keep it `lazy` and improves
8-
// performance, as we ultimately only need this publisher once in the
9-
// lifetime of the view.
6+
private final class Observed: ObservableObject {
107
lazy var objectWillChange = ObservableObjectPublisher()
11-
private var subscription: AnyCancellable?
12-
138
init() {}
14-
func relay(from storage: Storage) {
15-
defer { storage.objectWillSendIsRelayed = true }
16-
subscription = storage.object.objectWillChange.sink {
17-
[weak objectWillChange = self.objectWillChange] _ in
18-
guard let objectWillChange = objectWillChange else { return }
19-
objectWillChange.send()
20-
}
21-
}
229
}
2310

2411
private final class Storage {
25-
lazy var object: Object = initially()
26-
var objectWillSendIsRelayed: Bool = false
2712
var initially: (() -> Object)!
13+
lazy var object: Object = initially()
14+
private var objectWillChange: ObservableObjectPublisher?
15+
private var subscription: AnyCancellable?
16+
17+
func forwardObjectWillChange(to objectWillChange: ObservableObjectPublisher) {
18+
self.objectWillChange = objectWillChange
19+
20+
if subscription == nil {
21+
subscription = object.objectWillChange.sink { [weak self] _ in
22+
guard let objectWillChange = self?.objectWillChange else { return }
23+
objectWillChange.send()
24+
}
25+
}
26+
}
27+
2828
init() {}
2929
}
3030

31-
@ObservedObject private var objectWillChange = ObjectWillChange()
31+
@ObservedObject private var observedObject = Observed()
3232
@State private var storage = Storage()
3333

3434
init(wrappedValue: @autoclosure @escaping () -> Object) {
3535
storage.initially = wrappedValue
3636
}
3737

3838
func update() {
39-
if !storage.objectWillSendIsRelayed {
40-
// `View` invalidation still seems to be effective even if the `objectWillChange`
41-
// publisher is issued from another `@ObservedObject` instance than the current
42-
// one. It is likely that these publishers are bound to the `View`'s identity.
43-
objectWillChange.relay(from: storage)
44-
}
39+
storage.forwardObjectWillChange(to: observedObject.objectWillChange)
4540
}
4641

4742
var wrappedValue: Object {

0 commit comments

Comments
 (0)