Created
March 26, 2020 01:54
-
-
Save JimRoepcke/ac7d95d71fa3261715748f6589cda5c9 to your computer and use it in GitHub Desktop.
Change in Swift behaviour with didSet property observer for @published property in Xcode 11.4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
In Xcode 11.3.1, the output is: | |
>>> setting n to -1 | |
sending value through valueDidChange publisher | |
situation negative("hello") | |
<<< done | |
>>> setting n to 1 | |
sending value through valueDidChange publisher | |
situation positive("hello") | |
<<< done | |
>>> setting n to 1 | |
sending value through valueDidChange publisher | |
situation positive("hello") | |
<<< done | |
>>> setting n to 0 | |
sending value through valueDidChange publisher | |
situation zero | |
<<< done | |
In Xcode 11.4, the output is: | |
>>> setting n to -1 | |
<<< done | |
>>> setting n to 1 | |
<<< done | |
>>> setting n to 1 | |
<<< done | |
>>> setting n to 0 | |
<<< done | |
*/ | |
import Foundation | |
import Combine | |
enum Situation { | |
case positive(String) | |
case zero | |
case negative(String) | |
} | |
struct Thing { | |
var n: Int | |
var s: String | |
var situation: Situation { | |
if n > 0 { | |
return .positive(s) | |
} else if n < 0 { | |
return .negative(s) | |
} | |
return .zero | |
} | |
} | |
public typealias Reducer<Value, Action> = (inout Value, Action) -> Void | |
class Store<Value, Action>: ObservableObject { | |
public fileprivate(set) var reducer: Reducer<Value, Action> | |
@Published public fileprivate(set) var value: Value { | |
didSet { | |
print(" sending value through valueDidChange publisher") | |
valueDidChange.send(value) | |
} | |
} | |
let valueDidChange = PassthroughSubject<Value, Never>() | |
init(initialValue: Value, reducer: @escaping Reducer<Value, Action>) { | |
self.reducer = reducer | |
self.value = initialValue | |
} | |
func send(action: Action) { | |
self.reducer(&self.value, action) | |
} | |
} | |
let reducer: Reducer<Thing, Int> = { value, action in | |
value.n += action | |
value.s += "\(action)" | |
} | |
let store = Store<Thing, Int>( | |
initialValue: Thing(n: 0, s: "hello"), | |
reducer: reducer | |
) | |
let situationCancellable = store.valueDidChange | |
.map(\.situation) | |
.sink { situation in print(" situation", situation) } | |
print(">>> setting n to -1") | |
store.value.n = -1 | |
print("<<< done") | |
print(">>> setting n to 1") | |
store.value.n = 1 | |
print("<<< done") | |
print(">>> setting n to 1") | |
store.value.n = 1 | |
print("<<< done") | |
print(">>> setting n to 0") | |
store.value.n = 0 | |
print("<<< done") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment