在Swift中每隔x分钟做一些事情

JOS*_*Ftw 102 repeat intervals setinterval ios swift

我怎么能每分钟运行一个功能?在JavaScript中我可以做类似的事情setInterval,在Swift中存在类似的东西吗?

通缉输出:

你好世界每分钟一次......

Unh*_*lig 161

var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)

func sayHello() 
{
    NSLog("hello World")
}
Run Code Online (Sandbox Code Playgroud)

记得导入Foundation.

斯威夫特4:

 var helloWorldTimer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(ViewController.sayHello), userInfo: nil, repeats: true)

 @objc func sayHello() 
 {
     NSLog("hello World")
 }
Run Code Online (Sandbox Code Playgroud)

  • @Cing取决于自我指的是什么. (5认同)

Rob*_*Rob 128

在Swift 3中,您可以创建一个Timer.如果针对iOS 10及更高版本,您可以使用基于块的再现,这简化了潜在的强引用周期,例如:

weak var timer: Timer?

func startTimer() {
    timer?.invalidate()   // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it
    timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [weak self] _ in
        // do something here
    }
}

func stopTimer() {
    timer?.invalidate()
}

// if appropriate, make sure to stop your timer in `deinit`

deinit {
    stopTimer()
}
Run Code Online (Sandbox Code Playgroud)

在Swift 2中,您创建了一个NSTimer.如果你使用的是Swift 2,你很可能会使用10.0之前的iOS版本,在这种情况下你必须使用旧的target/ selectorpattern:

weak var timer: NSTimer?

func startTimer() {
    timer?.invalidate()   // just in case you had existing `NSTimer`, `invalidate` it before we lose our reference to it
    timer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)
}

func handleTimer(timer: NSTimer) {
    // do something here
}

func stopTimer() {
    timer?.invalidate()
}

// because this old target/selector approach will keep a strong reference
// to the `target`, if you want the timer to stop when the view controller
// is dismissed, you can't stop the timer in `deinit`, but rather have to 
// detect the dismissing of the view controller using other mechanisms. Commonly,
// we used to detect the view disappearing, like below:

override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)
    stopTimer()
}
Run Code Online (Sandbox Code Playgroud)

虽然NSTimer通常是最好的,但为了完整起见,我应该注意你也可以使用调度计时器,这对于在后台线程上调度计时器很有用.使用调度计时器,因为它们是基于块的,所以只要您使用引用,它就可以避免旧的target/ selector模式的一些强大的参考周期挑战.NSTimerweak

所以,在Swift 3中:

var timer: DispatchSourceTimer?

func startTimer() {
    let queue = DispatchQueue(label: "com.domain.app.timer")  // you can also use `DispatchQueue.main`, if you want
    timer = DispatchSource.makeTimerSource(queue: queue)
    timer!.scheduleRepeating(deadline: .now(), interval: .seconds(60))
    timer!.setEventHandler { [weak self] in
        // do whatever you want here
    }
    timer!.resume()
}

func stopTimer() {
    timer?.cancel()
    timer = nil
}

deinit {
    self.stopTimer()
}
Run Code Online (Sandbox Code Playgroud)

在Swift 2中:

var timer: dispatch_source_t?

func startTimer() {
    let queue = dispatch_queue_create("com.domain.app.timer", nil) // again, you can use `dispatch_get_main_queue()` if you want to use the main queue
    timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)
    dispatch_source_set_timer(timer!, DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC, 1 * NSEC_PER_SEC) // every 60 seconds, with leeway of 1 second
    dispatch_source_set_event_handler(timer!) { [weak self] in
        // do whatever you want here
    }
    dispatch_resume(timer!)
}

func stopTimer() {
    if let timer = timer {
        dispatch_source_cancel(timer)
        self.timer = nil
    }
}

deinit {
    self.stopTimer()
}
Run Code Online (Sandbox Code Playgroud)

欲了解更多信息,请参阅在创建一个定时器的部分调度来源的例子调度资源的部分并发编程指南.


Joh*_*n T 16

这是对使用闭包而不是命名函数的NSTimerSwift 3(其中NSTimer已重命名为Timer)的答案的更新:

var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
    (_) in
    print("Hello world")
}
Run Code Online (Sandbox Code Playgroud)

  • 这只适用于iOS 10. (6认同)

Bas*_*Bas 11

您可以使用 NSTimer

var timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true)
Run Code Online (Sandbox Code Playgroud)

在selector()中输入你的函数名


alg*_*rid 10

如果您可以允许一些时间漂移,这是一个简单的解决方案,每分钟执行一些代码:

private func executeRepeatedly() {
    // put your code here

    DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
        self?.executeRepeatedly()
    }
}
Run Code Online (Sandbox Code Playgroud)

只需运行executeRepeatedly()一次,它将每分钟执行一次。self释放拥有对象()时,执行停止。您还可以使用标志来指示必须停止执行。


Can*_*Can 7

在swift 3.0中,GCD被重构:

let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)

timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
    NSLog("Hello World")
}
timer.resume()
Run Code Online (Sandbox Code Playgroud)

当您需要在特定队列上分派时,这特别有用.此外,如果您计划将其用于用户界面更新,我建议调查CADisplayLink它与GPU刷新率同步.