How to cancel specific Operation from OperationQueue in swift
Asked Answered
C

3

5

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

Casease answered 27/1, 2020 at 7:35 Comment(2)
op2.cancel() doesn't work?Casper
yes it works for op2 but for other it won't workedMalita
M
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.

Millpond answered 27/1, 2020 at 8:51 Comment(0)
F
4

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("🐶")
        }
    }
}
Foss answered 27/1, 2020 at 7:53 Comment(0)
M
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.

Millpond answered 27/1, 2020 at 8:51 Comment(0)
M
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()
}
Makedamakefast answered 28/1, 2020 at 12:35 Comment(1)
Excerpt from apple's Foundation.NSOperation.swift: "access to operations is inherently a race condition, it should not be used"Blackberry

© 2022 - 2025 — McMap. All rights reserved.