取消OperationQueue迅速

问题描述 投票:2回答:1

我正在学习OperationQueue。我想做的是阻止正在进行的通话时的网络通话。问题是,当我点击按钮时,新操作正在添加到队列中。

class ViewController: UIViewController {

    private var queue = OperationQueue()

    func networkCall(completion: (()->Void)?) {
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
            completion?()
        }
    }

    lazy var button: UIButton = {
        let b = UIButton(type: .custom)
        b.backgroundColor = .black
        b.setTitleColor(.white, for: .normal)
        b.setTitle("CLICK!~", for: .normal)
        b.addTarget(self, action: #selector(self.boom), for: .touchUpInside)
        return b
    }()

    @objc func boom() {
        print("BOOM!")

        self.queue.maxConcurrentOperationCount = 1

        let block = BlockOperation()
        block.addExecutionBlock {
            self.networkCall {
                print("DONE NETWORK CALL!")
            }
        }

        self.queue.addOperation(block)

        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
            self.queue.cancelAllOperations()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .gray
        self.view.addSubview(self.button)
        self.button.translatesAutoresizingMaskIntoConstraints = false
        self.button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        self.button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        self.button.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
        self.button.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
    }
}

我想念什么吗?

swift nsoperationqueue
1个回答
0
投票

[遗憾的是,您不能只向BlockOperation添加异步方法。该操作本身将在提交异步网络请求后立即完成(即使您将completion?()延迟了任意3秒钟之后)。

相反,您将需要将网络请求包装在一个自定义的异步Operation子类方法中,该方法将执行所有KVO通知以实现正确的Operation行为。有关详细信息,请参见Operation documentation

例如,关于https://stackoverflow.com/a/32322851/1271826实现请参见downloadTask。或参见https://stackoverflow.com/a/48104095/1271826进行一般讨论。


[顺便说一下,即使您不会使用BlockOperation,在这种情况下,也请注意addExecutionBlockBlockOperation。例如,您可以有一个串行队列,创建一个BlockOperation,然后为给定的操作添加多个addExecutionBlock,它们将不会是串行的。单个操作将按顺序执行,但添加到给定BlockOperation中的单个块则不会执行。我通常建议人们避免addExecutionBlockBlockOperation,直到您真正了解那里发生的事情为止。初始化BlockOperation时最好只使用主闭包。

© www.soinside.com 2019 - 2024. All rights reserved.