apollo-ios
apollo-ios copied to clipboard
GraphQLQueryWatcher retained by ApolloStore
I might be missing something here, but it seems to me like a GraphQLQueryWatcher that is not cancelled explicitly is retained by the ApolloStore and will continue to receive updates, even if the object that created the watcher (by calling watch()) releases it.
Do I need to be ensuring that I manually cancel() my GraphQLQueryWatcher every time I'm done with it? It would be nice if, when I have no retain on the watcher, it automatically cancels.
If I'm missing something and it already works this way, then please let me know and close this!
Thanks
Hi @AnthonyMDev,
I have same issue do you find any solution?
Thanks
Yeah not having to manually cancel would certainly be ideal, but I don't think that's how things are set up at the moment. I'll have to see how plausible that is, though I don't have an ETA for you at the moment.
It seems to me like the solution would just be having the watcher call cancel() on itself in it's own deinit block.
If it's being retained by the Apollo store, wouldn't deinit never get called?
Ahhhh I looked at this last quite a while ago. I forgot about that part. Yes, we would need to figure that out.
@casey-chow That...might be difficult given that we don't (and don't intend to) use Rx on this project 😃
Would be a breaking change, but making the store not retain the watcher, and require the developer to retain a reference to the watcher for as long as it's needing the watcher could work, right?
I also expected that query watcher would unsubscribe itself once I release all references to it. Maybe documentation needs to stress this even more, with a - warning: .
One can create a dedicated object to unsubscribe query watcher from Apollo store upon it's deallocation. That simplified the code in my project a bit.
final class ApolloWatcherHandle<Query>: QueryWatcher where Query: Apollo.GraphQLQuery {
private let watcher: GraphQLQueryWatcher<Query>
init(watcher: GraphQLQueryWatcher<Query>) {
self.watcher = watcher
}
deinit {
watcher.cancel()
}
}
Probably not a bad idea to throw something into the docs on this for now. I do think long term it'd be nice to be able to auto-unsubscribe but this is way down the backlog, alas.
I actually really like @wnagrodzki 's solution here.
This may be fixed now by @gpambrozio's PR #1826. But if not, @wnagrodzki gave me the idea of making the watcher that the store retains opaque and exposing a wrapper that handles cancellation on deinit.