antoninbiret / RxEureka

This library is a small RxSwift wrapper around Eureka
MIT License
37 stars 9 forks source link

Memory Leak #7

Closed marbetschar closed 6 years ago

marbetschar commented 6 years ago

I was running into a memory leak adopting your Reactive extension which was quite huge, if it is adopted to the ImageRow.

Basically the issue was, that self.base was referenced directly and therefore was never released. That said, this code causes the leak (taken from here):

public var value: ControlProperty<String?> {
    let source = Observable<String?>.create { observer in
        observer.onNext(self.base.value)
        self.base.onChange({ (row) in //<---- this `self.base` reference causes the leak
            observer.onNext(row.value)
        })
        return Disposables.create {
            observer.onCompleted()
        }
    }
    let bindingObserver = BindableObserver(container: self.base) { (row, value) in
        row.value = value
    }
    return ControlProperty(values: source, valueSink: bindingObserver)
}

We can resolve this by using a local Optional which references base and is released on disposal:

public var value: ControlProperty<String?> {
    let source = Observable<String?>.create { observer in
        var base: Base? = self.base

        observer.onNext(base?.value)
        base?.onChange({ (row) in
            observer.onNext(row.value)
        })
        return Disposables.create {
            base = nil
            observer.onCompleted()
        }
    }
    let bindingObserver = BindableObserver(container: self.base) { (row, value) in
        row.value = value
    }
    return ControlProperty(values: source, valueSink: bindingObserver)
}
antoninbiret commented 6 years ago

Thank for reporting this issue (and give as much insights). I'll merge #11 when the review is done.

antoninbiret commented 6 years ago

Fixed in #14