Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Combine how Set<AnyCancellable> works?

Tags:

I have ViewModel with disposable Set defined this way

class ViewModel { 


 private var disposables = Set<AnyCancellable>()

 func sync() { 
    repo.syncObjects()
            .handleEvents(receiveCancel: {
                print("Synced objects: CANCELED!")
            })
            .sink(receiveCompletion: { completion in
                switch completion {
                case .failure(let error):
                    print("Synced objects: \(error)")
                case .finished:
                    print("Synced objects: finished")
                }
            }) { objects in
                print("Synced objects: \(objects)")
            }.store(in: &disposables)
 }

  deinit { print("ViewModel deinit") }
}

I am calling sync() in onAppear in SwiftUI view. Then I am fast switching screens and ViewModel referenced from SwiftUI view is deallocated by ARC like deinit is called but subscriptions seems to remain alive and disposable reference does not cancel subscription it fetches data from Network and saved them in Core Data and prints Synced objects: objects, Synced objects: finished. And keeps being alive even when I stop switching screens for several seconds to complete old requests.

Should I manually cancel AnyCancellable? shouldn't it be cancelled automagically?

like image 639
Michał Ziobro Avatar asked May 19 '20 10:05

Michał Ziobro


People also ask

What is Anycancellable in combine?

A type-erasing cancellable object that executes a provided closure when canceled.

How does swift combine work?

Overview. The Combine framework provides a declarative Swift API for processing values over time. These values can represent many kinds of asynchronous events. Combine declares publishers to expose values that can change over time, and subscribers to receive those values from the publishers.

What is sink in combine?

What's a sink? While a complete explanation of Combine, publishers, subscribers, and sinks is beyond the scope of this article, for our purposes here it's probably enough to know that in Combine a sink is the code receives data and completion events or errors from a publisher and deals with them.

What is PassthroughSubject?

A PassthroughSubject broadcasts elements to downstream subscribers and provides a convenient way to adapt existing imperative code to Combine. As the name suggests, this type of subject only passes through values meaning that it does not capture any state and will drop values if there aren't any subscribers set.


1 Answers

No, you dont need to cancel any cancellable because this kind of object calls the method cancel when deinitialized. So your code is correct.

Apple's documentation of AnyCancellable:

An AnyCancellable instance automatically calls cancel() when deinitialized

https://developer.apple.com/documentation/combine/anycancellable

like image 100
93sauu Avatar answered Oct 12 '22 11:10

93sauu