-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dispose viewConnectable synchronously #190
Conversation
Codecov Report
@@ Coverage Diff @@
## master #190 +/- ##
==========================================
- Coverage 95.37% 94.97% -0.40%
==========================================
Files 42 42
Lines 1427 1414 -13
==========================================
- Hits 1361 1343 -18
- Misses 66 71 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
guard status != .pendingDispose else { return } | ||
protectedConsumer.read { consumer in | ||
guard let consumer = consumer else { | ||
MobiusHooks.errorHandler("cannot consume value after dispose", #file, #line) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous code had an issue with retaining the consumer reference, which would lead to a somewhat nebulous crash when its unowned loop reference was accessed by emitting an event after disposal. This code is functionally equivalent, but the cause of the error should be clearer now.
guard state.running else { | ||
MobiusHooks.errorHandler("\(Self.debugTag): cannot accept events when stopped", #file, #line) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to this closure being created and owned by the loop—and the lifetime of the loop being tied to the controller's running state—this doesn't appear to be a valid scenario, unless the loop reference was somehow leaking.
43ce033
to
dfd370a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense to me. Might still be good to get some of the original Mobius.swift folks to look it over as you mentioned.
@JensAyton would you mind taking a look? I think you probably have the most insight into the existing implementation. |
Asynchronously disposing the controller view connection can lead to unexpected behavior (and ultimately crashes) in certain scenarios. It also differs from how other types (effect handler, event source, loop) are disposed: synchronously on the loop queue.
This contrived example demonstrates how the current implementation will lead to a crash:
As I wasn't involved in the original design it's possible I'm missing some important context, but I've attempted to annotate my reasoning for the changes as review comments.