You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I guess I'm confused on how Disposables should work. I have a UITableViewCell subclass with a viewModel property. On didSet of the viewModel I'm calling the following function:
The Code
privatefunc setupBindings(){
if let friendViewModel = friendViewModel {
disposableBindings += friendViewModel.statusLabel.producer.startWithNext({ status inself.statusLabel.text = status
})}}
The friendViewModel has a MutableProperty called statusLabel which looks like:
letstatusLabel=MutableProperty<String>("")
That disposableBindings property is a CompositeDisposable, which I'm "disposing" in an overridden prepareForReuse() method, like:
The issue is that the statusLabel isn't being updated anytime after the first signal is being sent. I've debugged this and prepareForReuse() isn't being called. When I add logEvents() like ...producer.logEvents().startWithNext({... I get output in the console like:
I'm confused why an Interrupted event is being sent on the producer? This is a MutableProperty, so I'm not sure why Interrupted would be sent. I should add that through trial and error, I've found that just ignoring the disposable solves the problem:
friendViewModel.statusLabel.producer.logEvents().startWithNext({ status inself.statusLabel.text = status
})
However, as expected, I'm pretty sure this is inducing other problems where reused cells don't have the signals from previous invocations of setupBindings() disposed and they're changing the statusLabel text with values from the wrong view model's statusLabelMutableProperty producer.
What am I missing here?
The text was updated successfully, but these errors were encountered:
If you dispose of the started producers (aka the produced signal), you would need to re-establish then.
Moreover, a disposed Disposable cannot be reused, and in your case the CompositeDisposable has to be replaced with a new instance on reuse.
That's said you may consider instead storing the view model in a MutableProperty and use flatMap to achieve the same goal.
// Assume viewModel is optional.
viewModel.producer.ignoreNil()
.flatMap(.latest) { $0.statusLabel.producer }
This way you won't have to manage disposables on your own, while bindings are automatically handled when you update the view model property. You just need to bind these flattened producers once to their destination, e.g. in awakeFromNib.
P.S. You can flatten properties directly in Swift 3.0.
@andersio thank you that's awesome! Fixes my problem and much cleaner.
Also, just FYI your explanation also helped. When I changed the code to instead be:
privatevardisposableBindings=CompositeDisposable()privatefunc setupBindings(){
disposableBindings += friendViewModel.statusLabel.producer.startWithNext({ status inself.statusLabel.text = status
})}}overridefunc prepareForReuse(){
disposableBindings.dispose()
disposableBindings =CompositeDisposable()}
The signal is persisting until cell reuse. I think the problem was from me reusing CompositeDisposable. I was treating it more like an NSCache or something.
I guess I'm confused on how
Disposable
s should work. I have aUITableViewCell
subclass with aviewModel
property. OndidSet
of theviewModel
I'm calling the following function:The Code
The
friendViewModel
has aMutableProperty
calledstatusLabel
which looks like:That
disposableBindings
property is aCompositeDisposable
, which I'm "disposing" in an overriddenprepareForReuse()
method, like:The Problem
The issue is that the
statusLabel
isn't being updated anytime after the first signal is being sent. I've debugged this andprepareForReuse()
isn't being called. When I addlogEvents()
like...producer.logEvents().startWithNext({...
I get output in the console like:I'm confused why an
Interrupted
event is being sent on the producer? This is aMutableProperty
, so I'm not sure why Interrupted would be sent. I should add that through trial and error, I've found that just ignoring the disposable solves the problem:However, as expected, I'm pretty sure this is inducing other problems where reused cells don't have the signals from previous invocations of
setupBindings()
disposed and they're changing thestatusLabel
text with values from the wrong view model'sstatusLabel
MutableProperty
producer.What am I missing here?
The text was updated successfully, but these errors were encountered: