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?
A type-erasing cancellable object that executes a provided closure when canceled.
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'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.
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.
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 deinitializedhttps://developer.apple.com/documentation/combine/anycancellable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With