4

There are 3 Operations in my OperationQueue and i'm not able to cancel specific operation from them.

I referred this example but i can't understand it NSOperationQueue cancel specific operations

This is my code

class myOperation1 : Operation {

    override func main() {

        print("op1 () working....")

        for i in 1...10 {
            print("")
        }
    }
}

class myOperation2 : Operation {

    override func main() {

        print("op2 () working....")

        for i in 1...10 {
            print("")
        }
    }
}

class myOperation3 : Operation {

    override func main() {

        print("op3 () working....")
        for i in 1...10 {
            print("")
        }
    }
}

let op1 = myOperation1()
let op2 = myOperation2()
let op3 = myOperation3()

op1.completionBlock = {
    print("op1 () completed")
}

op2.completionBlock = {
    print("op2 () completed")
}

op3.completionBlock = {
    print("op3 () completed")
}

let opsQue = OperationQueue()
opsQue.addOperations([op1, op2, op3], waitUntilFinished: false)

DispatchQueue.global().asyncAfter(deadline: .now()) {
    opsQue.cancelAllOperations()
}

Inshort i want to cancel second operation from operationQueue.

Please guide me.

Thank you

NøBi Mac
  • 505
  • 5
  • 15

3 Answers3

4

you can call op2.cancel() to cancel the operation, but you need to take additional steps to really stop your operation from running as cancel() only set the isCanceled property to true.

Please check the developer document. https://developer.apple.com/documentation/foundation/operation/1408418-iscancelled

The default value of this property is false. Calling the cancel() method of this object sets the value of this property to true. Once canceled, an operation must move to the finished state.

Canceling an operation does not actively stop the receiver’s code from executing. An operation object is responsible for calling this method periodically and stopping itself if the method returns true.

You should always check the value of this property before doing any work towards accomplishing the operation’s task, which typically means checking it at the beginning of your custom main() method. It is possible for an operation to be cancelled before it begins executing or at any time while it is executing. Therefore, checking the value at the beginning of your main() method (and periodically throughout that method) lets you exit as quickly as possible when an operation is cancelled.

Community
  • 1
  • 1
Mike.Zhou
  • 136
  • 1
  • 4
3

opsQue.cancelAllOperations() in your code cause removing non-started operations from queue and calls Operation.cancel() for each executing operation, but it only set isCancelled to true. You need to handle it explicitly

class myOperation2 : Operation {

    override func main() {

        print("op2 () working....")

        for i in 1...10 {
            if self.isCancelled { break } // cancelled, so interrupt
            print("")
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
2

Hope you referred to the documentation for Operation

There are several KVO-Compliant Properties for observe operation.

There is one property isCancelled - read-only

used to check this property before the execution of the operation

like this:

class myOperation2 : Operation {

    override func main() {

        print("op2 () working....")

        if self.isCancelled {
            return
        }

        for i in 1...10 {
            print("")
        }
    }
}

and for cancelation:

DispatchQueue.global().asyncAfter(deadline: .now()) {
    opsQue.operations[1].cancel()
}
Raj Aryan
  • 23
  • 4
  • Excerpt from apple's `Foundation.NSOperation.swift`: "access to operations is inherently a race condition, it should not be used" – elight Apr 15 '20 at 22:07