Search code examples
iosswiftxcodetimernstimer

How to use a timer to stop a long-running function? Swift 4


I have a function that runs for a long time, and I'd like to give it a cap of 10 seconds if possible. I'd also like to implement a Cancel button for the user to press as well.

I tried simply checking the status of a var abort while it calculates, but it just continues working. I'm not very skilled with Grand Central Dispatch and timers and don't know where to go from here.

...



var abort = false

@objc func abortCalculations() {
    abort = true
}


func calculate() {
    abort = false

    let _ = Timer(timeInterval: 10, target: self, selector: #selector(abortCalculations), userInfo: nil, repeats: false)



    dispatchGroup.enter()
    DispatchQueue.global(qos: .userInteractive).async {
        while !abort {
            x += 1 // for example, just something that repeats
                    // when this actually finishes, it leaves the dispatch group
        }
    }
}



...

I'd like the function calculate() to finish when the timer stops it (or when a user presses a button, in the future). Instead, it continues to run and the function abortCalculations() is never called.


Solution

  • Instead of using a Timer, you can use a similar DispatchQueue to set your abort flag.

    var abortFlagItem = DispatchWorkItem(block: {
        self.abort = true
    })
    DispatchQueue.main.asyncAfter(deadline: .now() + 10, execute: abortFlagItem)
    

    At any point if you want to cancel, you can call abortFlagItem.cancel()