Reputation: 539
Is it my responsibility to maintain a reference to a Signal
or a SignalProducer
, e.g., using an instance variable?
In other words, will they automatically disappear and stop sending events when they get deallocated?
Upvotes: 1
Views: 316
Reputation: 371
FYI, not necessary, the Signal
will be disposed and stop forwarding events.
Signal
is a class type, if no one have a reference to it, it should be deinit.
However, Signal
implementation introduces a tricky way to retain itself, see state
property, so that there exists some memory leaks in temporary. As seen in source code, if there have some observers subscribe on the Signal
, it's state
does retain it in turn until all observers unsubscribed or the Signal
received completed/error/interrupted event.
Here some marked code snippets.
// definition of SignalState
private struct SignalState<Value, Error: Swift.Error> {
var observers: Bag<Signal<Value, Error>.Observer> = Bag()
var retainedSignal: Signal<Value, Error>? // here is the key
}
public func observe(_ observer: Observer) -> Disposable? {
var token: RemovalToken?
state.modify {
$0?.retainedSignal = self // retain self when one observer on
token = $0?.observers.insert(observer)
}
if let token = token {
return ActionDisposable { [weak self] in
if let strongSelf = self {
strongSelf.state.modify { state in
state?.observers.remove(using: token)
if state?.observers.isEmpty ?? false {
// break retain cycle when disposed
state!.retainedSignal = nil
}
}
}
}
} else {
observer.sendInterrupted()
return nil
}
}
How about SignalProducer
?
It is really intuitive, SignalProducer
is just struct
type, and you should not consider its lifetime.
Upvotes: 3