【问题标题】:How to cancel specific Operation from OperationQueue in swift如何快速取消 OperationQueue 中的特定操作
【发布时间】:2020-01-27 07:35:11
【问题描述】:

我的 OperationQueue 中有 3 个操作,我无法从中取消特定操作。

我提到了这个例子,但我无法理解 NSOperationQueue cancel specific operations

这是我的代码

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

简而言之,我想从 operationQueue 中取消第二个操作。

请指导我。

谢谢

【问题讨论】:

  • op2.cancel() 不起作用?
  • 是的,它适用于op2,但对于其他它不起作用

标签: ios nsoperationqueue nsoperation


【解决方案1】:

您可以调用 op2.cancel() 来取消操作,但您需要采取额外的步骤才能真正停止操作,因为 cancel() 只需将 isCanceled 属性设置为 true。

请查看开发者文档。 https://developer.apple.com/documentation/foundation/operation/1408418-iscancelled

此属性的默认值为 false。调用此对象的 cancel() 方法会将此属性的值设置为 true。一旦取消,操作必须进入完成状态。

取消操作不会主动停止接收者的代码执行。操作对象负责定期调用此方法,如果方法返回 true,则自行停止。

在完成操作任务之前,您应该始终检查此属性的值,这通常意味着在自定义 main() 方法的开头检查它。可以在操作开始执行之前或在执行期间的任何时间取消操作。因此,检查 main() 方法开头的值(并在整个方法中定期检查)可以让您在操作被取消时尽快退出。

【讨论】:

    【解决方案2】:

    opsQue.cancelAllOperations() 在您的代码中导致从队列中删除 未启动 操作并为每个正在执行的操作调用 Operation.cancel(),但它仅将 isCancelled 设置为 true。你需要明确地处理它

    class myOperation2 : Operation {
    
        override func main() {
    
            print("op2 (?) working....")
    
            for i in 1...10 {
                if self.isCancelled { break } // cancelled, so interrupt
                print("?")
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      希望你参考documentation for Operation

      有几个KVO-Compliant属性用于观察操作。

      有一个属性isCancelled - read-only

      用于在操作执行前检查该属性

      像这样:

      class myOperation2 : Operation {
      
          override func main() {
      
              print("op2 (?) working....")
      
              if self.isCancelled {
                  return
              }
      
              for i in 1...10 {
                  print("?")
              }
          }
      }
      

      以及取消:

      DispatchQueue.global().asyncAfter(deadline: .now()) {
          opsQue.operations[1].cancel()
      }
      

      【讨论】:

      • 摘自苹果的Foundation.NSOperation.swift:“访问操作本质上是一种竞争条件,不应使用它”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-19
      相关资源
      最近更新 更多