AsyncExtensions
AsyncExtensions copied to clipboard
[BUG] Memory Leak issue with flatMapLatest having inner asyncSequence
Describe the bug
Here is the sample code that we are using to reproduce the memory leak. We are expecting BatteryFeature to be de-allocated once we remove it from the features array
protocol Feature {}
class BatteryFeature: Feature {
private let sub = AsyncCurrentValueSubject<Double>(50)
var batteryLabel: AnyAsyncSequence<Double>
init() {
self.batteryLabel = sub.eraseToAnyAsyncSequence()
}
deinit {
print("BatteryFeature Deinit")
}
}
class Device {
var features = [AnyAsyncSequence<Feature>]()
init() {
let feature: AnyAsyncSequence<Feature> = AsyncJustSequence(BatteryFeature()).eraseToAnyAsyncSequence()
features.append(feature)
}
}
class Provider {
private let device = Device()
func getDevice() -> AnyAsyncSequence<Device> {
AsyncJustSequence(device).eraseToAnyAsyncSequence()
}
func remove() {
device.features.removeFirst()
}
}
class BatteryVM: ObservableObject {
private let provider = Provider()
@Published var batteryLbl: Double = 0
init() {
let result: AnyAsyncSequence<Double> = provider.getDevice().flatMapLatest { device -> AnyAsyncSequence<Double> in
let featureSeq: AnyAsyncSequence<Feature> = device.features.first!
let v: AnyAsyncSequence<Double> = featureSeq.flatMap { feature -> AnyAsyncSequence<Double> in
let bat = feature as! BatteryFeature
return bat.batteryLabel
}.eraseToAnyAsyncSequence()
return v
}.eraseToAnyAsyncSequence()
Task { [weak self, result] in
for try await value in result {
print("Bat: \(value)")
await MainActor.run { [weak self] in
self?.batteryLbl = value
}
}
}
}
func remove() {
provider.remove()
}
deinit {
print("BatteryVM Deinit")
}
}
Environment:
- Version of the library: 0.5.2