Here's a Swift class that uses ReactiveSwift, wrapping a MutableProperty
in a Property
, and adding a subscription to that Property
in a ScopedDisposable
:
class Leaker {
let mutableProperty = MutableProperty<Int>(0)
var wrapperProperty: Property<Int> {
return Property(self.mutableProperty)
}
private var disposable: ScopedDisposable<AnyDisposable>?
init() {
let disposable = CompositeDisposable()
disposable += self.wrapperProperty.producer
.startWithValues { value in
print("\(value)")
}
self.disposable = ScopedDisposable(disposable)
}
}
If I give another class a property of type Leaker?
, and then set it using self.leaker = Leaker()
, this creates a leak. By "creates a leak," I mean it sets off the Leaks instrument, showing a leaked object labeled Malloc 32 Bytes
, with a stack trace that includes Leaker.init()
calling Leaker.wrapperProperty.getter
.
Why does this leak? I'm finding it hard to understand exactly what is causing the memory allocated here to never be released.
Some other facts that might be useful:
- This doesn't leak if I subscribe to
mutableProperty
directly - This doesn't leak if I wrap
mutableProperty
in a lazy property instead of a computed property - This doesn't leak if I create a temporary
Leaker
, e.g.let _ = Leaker()