@@ -3,45 +3,40 @@ import SwiftUI
3
3
4
4
@propertyWrapper
5
5
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 {
10
7
lazy var objectWillChange = ObservableObjectPublisher ( )
11
- private var subscription : AnyCancellable ?
12
-
13
8
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
- }
22
9
}
23
10
24
11
private final class Storage {
25
- lazy var object : Object = initially ( )
26
- var objectWillSendIsRelayed : Bool = false
27
12
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
+
28
28
init ( ) { }
29
29
}
30
30
31
- @ObservedObject private var objectWillChange = ObjectWillChange ( )
31
+ @ObservedObject private var observedObject = Observed ( )
32
32
@State private var storage = Storage ( )
33
33
34
34
init ( wrappedValue: @autoclosure @escaping ( ) -> Object ) {
35
35
storage. initially = wrappedValue
36
36
}
37
37
38
38
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)
45
40
}
46
41
47
42
var wrappedValue : Object {
0 commit comments