Skip to content

[BUG] Memory Leak issue with flatMapLatest having inner asyncSequence  #35

@dasmihir20

Description

@dasmihir20

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions