-
Notifications
You must be signed in to change notification settings - Fork 722
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
CancelBag Strong Reference Cycle #88
Comments
If u press button action several times it would not cancel previous requests |
Hey! I believe if you remove the binding from your sample code, the reference cycle should go away. It doesn't seem to be used for any state management in your code, just store the cancelBag in the view's Oh, I see you're referring to a similar structure in the codebase of the project. Thanks for the heads up, this might actually be an issue. I'll have a look when I get time! |
@nalexn Thanks for your response! |
My raw reimplementation of binding works perfectly instead of SwiftUI one's
This means that somewhere under the hood SwiftUI binding retains the value twice |
I have found a similar problem while writing directly to appState. The root cause differs, so even could suggest a fix for it.
Imagine u have some loadable in appState and it equals to
if the last value is equal, the old operation will never be canceled. Cause However, this approach will brake the tests, cause it XCTAssertsEqual will check for cancelBag as well. But this solutions could be solved by custom asserts |
Hi @nalexn! |
Hey - sorry for a slow response. Today I reviewed the existing code, so here are my thoughts. Now about the original concern about cancelBag being retained. In RxSwift we're relying on the disposeBag's deallocation for canceling the subscriptions, so retaining it anywhere except in the owning object is indeed a problem leading to subscription leaking. A peculiarity of SwiftUI is that almost everything is a struct, so you cannot use the same approach as with RxSwift due to the absence of "owning objects" limiting the lifetime of the subscriptions.
Loadable enum also offers So, to the solution: if you have an event in your app when you want to stop all running requests (for example, when the user logs out) - you can call |
Binding is a struct that has two properties get and set which are closures (my assumption as far as they are marked in init as escaping). That means that it retains its value. Looking at your interactors I have found that
sinkToLoadable
retains thecancelBag
, associated value of theloading
case. So, that means that the publisher will never be canceled if cancelBag receives dealloc message. For example, if the interactor's method will be called again before the previous publisher finishes. So settings any other new value to binding to replace the previousloading(_, cancelBag)
will not stop the publisher.Does it was the desired behavior?
The text was updated successfully, but these errors were encountered: