如何在 Swift 3.0 中停止来自 运行 的函数

How to stop a Function from Running in Swift 3.0

我有一个函数可以开始异步播放 运行 动画(在后台)。使用完成处理程序(见下文)无限期地调用此动画。有没有办法在按下另一个按钮时关闭此功能?

这是我的代码:

func showAnimation() {
    UIView.animate(withDuration: 1, animations: {
        animate1(imageView: self.Anime, images: self.animation1)
    }, completion: { (true) in
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            self.showAnimation() // replay first showAnimation
        }
    }) 
 }

然后按下另一个按钮,我们关闭上述功能

showAnimation().stop();

谢谢

有很多方法可以做到这一点。最简单的是在 asyncAfter 块中检查一个布尔值 属性 (你应该正确地使其成为原子),如果它是真的,不要再调用 showAnimation() .

您可以做的另一件事,也是我喜欢为更复杂的任务做的事情,是使用 OperationQueue 而不是 DispatchQueue。这允许您单独或一次取消操作,甚至暂停整个队列(显然不要暂停主队列或对其调用 removeAllOperations(),因为那里可能有其他不相关的操作到你的代码)。

您可以在 class 中添加一个 属性 作为标志,指示动画是否应该 运行。

var runAnimation = true

func showAnimation() {
    if !runAnimation { return }

    UIView.animate(withDuration: 1, animations: {
        animate1(imageView: self.Anime, images: self.animation1)
    }, completion: { (true) in
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            if runAnimation {
                self.showAnimation() // replay first showAnimation
            }
        }
    }) 
}

然后在按钮处理程序中停止动画,您只需执行以下操作:

runAnimation = false

请注意,这不会停止当前 运行ning 1 秒的动画。这只会阻止任何更多的动画。

您可以在您的函数之外提供一个变量,然后观察它的值并处理您的任务。我可以给你一个解决方案:

class SomeClass {

    private var shouldStopMyFunction: Bool = false // keep this private

    public var deadline: TimeInterval = 0

    func stopMyFunction() {
        shouldStopMyFunction = true
    }

    func myFunction(completionHanlder: @escaping (String)->()) {
        // -------
        var isTaskRunning = true
        func checkStop() {
            DispatchQueue.global(qos: .background).async {
                if self.shouldStopMyFunction, isTaskRunning {
                    isTaskRunning = false
                    completionHanlder("myFunction is forced to stop! ")
                } else {
                    //print("Checking...")
                    checkStop()
                }
            }
        }
        checkStop()
        // --------


        // Start your task from here

        DispatchQueue.global().async { // an async task for an example.
            DispatchQueue.global().asyncAfter(deadline: .now() + self.deadline, execute: {
                guard isTaskRunning else { return }
                isTaskRunning = false
                completionHanlder("My job takes \(self.deadline) seconds to finish")
            })
        }
    }
}

并实施:

let anObject = SomeClass()
anObject.deadline = 5.0 // seconds

anObject.myFunction { result in
    print(result)
}

let waitingTimeInterval = 3.0 // 6.0 // see `anObject.deadline`
DispatchQueue.main.asyncAfter(deadline: .now() + waitingTimeInterval) {
    anObject.stopMyFunction()
}

waitingTimeInterval = 3.0 的结果:myFunction is forced to stop!

waitingTimeInterval = 6.0 的结果:My job takes 5.0 seconds to finish