NøBi Mac
NøBi Mac

Reputation: 525

How to cancel specific Operation from OperationQueue in swift

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

Upvotes: 5

Views: 5531

Answers (3)

Raj Aryan
Raj Aryan

Reputation: 23

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()
}

Upvotes: 2

Mike.Zhou
Mike.Zhou

Reputation: 176

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.

Upvotes: 4

Asperi
Asperi

Reputation: 258127

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("🐶")
        }
    }
}

Upvotes: 4

Related Questions