I am having memory leak issue while iterating over async sequence like so:
import Foundation
import Combine
class MyServiceClass {
let timerSequence = Timer.publish(every: 1, on: .main, in: .default).autoconnect().values
init() {
Task { [weak self] in
await self?.setUpStreamIteration()
}
}
func setUpStreamIteration() async {
for await time in timerSequence {
print(time)
}
}
}
var service: MyServiceClass? = MyServiceClass()
service = nil
the task continues to run and print the time even after the screen\class is "dismissed".
Output:
2023-03-26 00:14:11 +0000
2023-03-26 00:14:12 +0000
2023-03-26 00:14:13 +0000
2023-03-26 00:14:14 +0000
2023-03-26 00:14:15 +0000
2023-03-26 00:14:16 +0000
2023-03-26 00:14:17 +0000
2023-03-26 00:14:18 +0000
2023-03-26 00:14:19 +0000
...
but when using .sink mechanism instead - I don't experience and memory leak.
the working example is:
import Foundation
import Combine
class MyServiceClass {
let timerSequence = Timer.publish(every: 1, on: .main, in: .default).autoconnect()
init() {
Task { [weak self] in
await self?.setUpStreamIteration()
}
}
func setUpStreamIteration() async {
await timerSequence
.sink { [weak self] time in
print(time)
}
.store(in: &cancellations)
}
}
var service: MyServiceClass? = MyServiceClass()
service = nil
can any one try to explain why using .sink managed to prevent the memory leak?
is it ok to use .sink always as oppose of iterating over async sequence?
can we compare the two approaches - to decide which one is better and why?
thanks!