NSOperations, dependencies and failed operations
Asked Answered
Z

3

6

I've started working with CloudKit and finally started using subclassed NSOperation for most of my async stuff.

How ever, I have two questions.

  1. How can I mark an operation as failed? That is, if operation A fails, I don't wan't its dependent operations to run. Can I just not mark it as isFinished? What happens to the unexecuted items already in the queue?

  2. What would be the recommended route to take if I would like something like a try, catch, finally. The end goal is to have one last operation that can display some UI with information of success or report errors back to the user?

Zeal answered 10/9, 2015 at 8:0 Comment(0)
K
1

isFinished means your operations complete execution, you can cancel an operation but that means your operation is canceled and that could be done without even executing the operation and you can check that by calling isCanceled, if you want spefically failure and success flags after executing an NSOperation then in subclass add isFailure property and check in dependent operation before executing, and cancel that if isFailure is set to true.

You can add dependency on operation and check there status, and if all are successful just update UI on main thread or report and error.

Update You can keep and array of dependent operations and when on failure you can cancel those operations.

Kevinkevina answered 10/9, 2015 at 8:8 Comment(2)
Ok, thanks. So the best way would be to keep a reference to each operation on the check the new isFailure property for all of them and display different messages depending the its value?Zeal
Yup you can keep reference to depended operations and when it fails or cancel you can make cancel them as well.Kevinkevina
S
0
  1. Add the operations to a queue. When one of them fails call cancel on the queue. Future CKOperations will error on start with "operation was cancelled before it started" and any block operations won't even run.

  2. One way is to use KVO on the queue's operationCount (Example on Github) and wait until it is zero. Then if you got an error at any stage (and captured it) you can make a final callback operation ended with the error. However, usually you will end up wanting to display a different message depending on the operation that caused the error, in which case it is best to handle them when they happen, rather than wait until the end when you then need to figure out which error came from which operation.

Sabatier answered 7/1, 2017 at 20:50 Comment(0)
P
0

Overview:

  • When an operation fails (based on your business logic) and you want to abort all dependant operations then you can cancel dependant operations manually

  • Order in which you cancel operation is important as cancelling an operation would allow for the dependant operations to start (as the dependancy condition has been broken).

  • In order to all this you need to have variables holding each of those dependant operations, so that you cancel them in the order you intend.

Code:

var number = 0

let queue = OperationQueue()

let b = BlockOperation()
let c = BlockOperation()
let d = BlockOperation()

let a = BlockOperation {
    
    if number == 1 {
    
        //Assume number should not be 1
        //If number is 1, then it is considered as a failure
        
        //Cancel the remaining operations manually in the reverse order
        //Reverse order is important because if you cancelled b first, it would start c
        d.cancel()
        c.cancel()
        b.cancel()
    }
}

b.addDependency(a)
c.addDependency(b)
d.addDependency(c)

queue.addOperation(a)
queue.addOperation(b)
queue.addOperation(c)
queue.addOperation(d)
Piatt answered 2/9, 2017 at 2:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.