Skip to content

Instantly share code, notes, and snippets.

@layoutSubviews
Created February 1, 2021 22:05
Show Gist options
  • Save layoutSubviews/f8d096aec301dc05b55dea8d1fe919da to your computer and use it in GitHub Desktop.
Save layoutSubviews/f8d096aec301dc05b55dea8d1fe919da to your computer and use it in GitHub Desktop.
Gist demonstrating Publishers.CombineLatest is racy
func testCombineLatest() {
for _ in 1...100 {
let e = expectation(description: "Each subject should emit true")
let s1 = CurrentValueSubject<Bool, Never>(false)
let s2 = CurrentValueSubject<Bool, Never>(false)
let cancellable = Publishers.CombineLatest(s1, s2)
.sink {
if $0, $1 {
e.fulfill()
}
}
for subject in [s1, s2] {
DispatchQueue.global().asyncAfter(deadline: .now() + .microseconds(10)) {
subject.send(true)
}
}
wait(for: [e], timeout: 5)
cancellable.cancel()
}
}
@OskarGroth
Copy link

You have to use the same serial queue for all Publishers that you would like to combine. After combining, you can dispatch the sink on any queue, concurrent or not:

class testcombineTests: XCTestCase {
    
    let queue = DispatchQueue(label: "MyQueue") // serial queue

    func testCombineLatest() {
        for _ in 1...100 {
            let e = expectation(description: "Each subject should emit true")
            let s1 = CurrentValueSubject<Bool, Never>(false)
            let s2 = CurrentValueSubject<Bool, Never>(false)
            let cancellable = Publishers.CombineLatest(s1.receive(on: queue), s2.receive(on: queue))
                .sink {
                    print("\(s1.value), \(s2.value)")
                    if $0, $1 {
                        e.fulfill()
                    }
                }
            for subject in [s1, s2] {
                DispatchQueue.global().asyncAfter(deadline: .now() + .microseconds(10)) {
                    subject.send(true)
                }
            }
            wait(for: [e], timeout: 15)
            cancellable.cancel()
        }
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment