Last active
May 2, 2021 17:38
-
-
Save fxm90/a32c8db5a2b29f1426369370d335c128 to your computer and use it in GitHub Desktop.
Gist showing the difference between the property wrapper `@Published` and a `CurrentValueSubject`
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
// | |
// CombinePublishedVsCurrentValueSubject.playground | |
// | |
// Created by Felix Mau on 09.02.21. | |
// Copyright © 2021 Felix Mau. All rights reserved. | |
// | |
import Foundation | |
import Combine | |
class PublishedTest { | |
/// > When the property changes, publishing occurs in the property’s `willSet` block, | |
/// > meaning subscribers receive the new value before it’s actually set on the property. | |
/// https://developer.apple.com/documentation/combine/published | |
@Published | |
var numberOfAdults: Int = 0 | |
} | |
class SubjectTest { | |
var numberOfAdults: Int { | |
get { numberOfAdultsSubject.value } | |
set { numberOfAdultsSubject.value = newValue } | |
} | |
var numberOfAdultsPublisher: AnyPublisher<Int, Never> { | |
numberOfAdultsSubject.eraseToAnyPublisher() | |
} | |
private let numberOfAdultsSubject = CurrentValueSubject<Int, Never>(0) | |
} | |
var subscriptions = Set<AnyCancellable>() | |
// MARK: - `@Published` Test | |
let publishedTest = PublishedTest() | |
publishedTest.$numberOfAdults.sink { [weak publishedTest] in | |
print("@Published: Value passed to closure", $0) | |
print("@Published: Value on class property", publishedTest!.numberOfAdults) // <- As `@Published` uses `willSet` the value is not updated here. | |
}.store(in: &subscriptions) | |
publishedTest.numberOfAdults = 1 | |
publishedTest.numberOfAdults = 2 | |
// Output | |
// | |
// @Published: Value passed to closure 0 | |
// @Published: Value on class property 0 | |
// @Published: Value passed to closure 1 ‼️ | |
// @Published: Value on class property 0 ‼️ | |
// @Published: Value passed to closure 2 ‼️ | |
// @Published: Value on class property 1 ‼️ | |
// | |
// -> Closure gets informed with initial value, therefore it seems like `@Published` uses a `CurrentValueSubject` internally. | |
// MARK: - `CurrentValueSubject` Test | |
let subjectTest = SubjectTest() | |
subjectTest.numberOfAdultsPublisher.sink { [weak subjectTest] in | |
print("CurrentValueSubject: Value passed to closure", $0) | |
print("CurrentValueSubject: Value on class property", subjectTest!.numberOfAdults) | |
}.store(in: &subscriptions) | |
subjectTest.numberOfAdults = 1 | |
subjectTest.numberOfAdults = 2 | |
// Output | |
// | |
// CurrentValueSubject: Value passed to closure 0 | |
// CurrentValueSubject: Value on class property 0 | |
// CurrentValueSubject: Value passed to closure 1 | |
// CurrentValueSubject: Value on class property 1 | |
// CurrentValueSubject: Value passed to closure 2 | |
// CurrentValueSubject: Value on class property 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment