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

5

我有一个函数,它开始播放一个异步运行的动画(在后台)。使用完成处理程序(见下文),无限期地调用此动画。是否有一种方法在按下另一个按钮时关闭此函数?

以下是我的代码:

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

谢谢

3个回答

6
您可以向类中添加一个属性,作为标志来指示是否应该运行动画。
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

请注意,这并不会停止当前正在运行的1秒动画。这只是防止更多的动画。

5

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

另一件事情是,对于更复杂的任务,我喜欢使用OperationQueue而不是DispatchQueue。这允许您取消操作,无论是单个操作还是全部操作,甚至暂停整个队列(显然不要暂停主队列或在其中调用removeAllOperations(),因为可能存在与您的代码无关的其他操作)。


2
你可以在函数外提供一个变量,然后观察它的值并处理你的任务。我可以给你一个解决方案:
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被强制停止!

waitingTimeInterval = 6.0的结果: 我的工作需要5.0秒才能完成


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接