-
Notifications
You must be signed in to change notification settings - Fork 7
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
Great work! #4
Comments
Oh and finish should probably take an NSError param, e.g. finishWithError and also pass it to finishOnDispatchQueueWithError I mentioned. This way the custom completion blocks can also supply an error param. |
Thanks @malhal ✨ I analysed your suggestion about creating a new method
Why do you think is important guarantee the invocation of completion block on the dispatch queue used internally? I'm asking that because the only purpose of that queue is change the internal state of the operation in a safely way. Another question is if we really need that explicit completion block or if we can rely on the Let me know your thoughts about this, I'm not against the change but currently I'm not seeing a strong reason to do that change. |
Hi thanks for taking the time to think about this! Very nice of you. I began writing an example to demonstrate the problem and I couldn't produce a concrete issue so I thought it would be better just to answer the questions, in reverse order if you don't mind. NSOperation's completionBlock and the next NSOperation in the queue run simultaneously. This means if using dependent operations it isn't possible to initialise a property on the next operation on the completion of the first, because it has already started. So we can't use that. Anyway we would want our own block so we can pass the result and error. Given this, we then have to resort to our completion block running on our own background thread we created in the async task. From there it's more tricky to explain why I think it would be better for a custom completion block to run on the dispatch queue instead of on that but I have some guesses. Maybe it would ensure safe manipulation of the operations running on the queue. Since say for example you get an error so in your completion block you make make the queue cancel all operations and if an operation overrides cancel, it is safer to be on the dispatch queue then. Also any calls to operation properties like isFinished result in a dispatch sync to the dispatch queue which seem unnecessary given the operation is about to finish. Maybe also to ensure the operation finishing is the next thing after the completion block ends without a delay to sync with the dispatch queue. Lastly I've been reverse engineering the CloudKit iOS API and they do it this way, then again they call the main from their dispatch queue so maybe that's their reason!
Methods of interest on CKOperation:
So that's my thoughts sorry if I was vague on the last answer and I understand if you don't see a strong reason in it. |
But could I suggest a small improvement: in the finish method, inside the perform block, if it called a new method finishOnDispatchQueue to set the state instead of setting it directly, then that method could be overridden by subclasses and allow them to call their own custom completion block and then calling super to change the state and end the operation. This way they can guarantee their completion block is called on the dispatch queue using your nifty code.
The text was updated successfully, but these errors were encountered: