Wie kann ich jede Minute eine Funktion ausführen? In JavaScript kann ich so etwas machensetInterval
, gibt es in Swift etwas Ähnliches?
Gewünschte Ausgabe:
Hallo Welt einmal in der Minute ...
Wie kann ich jede Minute eine Funktion ausführen? In JavaScript kann ich so etwas machensetInterval
, gibt es in Swift etwas Ähnliches?
Gewünschte Ausgabe:
Hallo Welt einmal in der Minute ...
Antworten:
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
Denken Sie daran, Foundation zu importieren.
Swift 4:
var helloWorldTimer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(ViewController.sayHello), userInfo: nil, repeats: true)
@objc func sayHello()
{
NSLog("hello World")
}
NSTimer
es das Ziel, so, mit dieser Einstellung behält, wenn helloWorldTimer
eine Eigenschaft auf self
Sie sich ein Zyklus behalten haben, wo self
behält helloWorldTimer
und helloWorldTimer
behält self
.
Wenn Sie auf iOS Version 10 und höher abzielen, können Sie die blockbasierte Wiedergabe von verwenden Timer
, die die potenziell starken Referenzzyklen vereinfacht, z.
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()
}
Obwohl dies Timer
der Vollständigkeit halber im Allgemeinen am besten ist, sollte ich beachten, dass Sie auch den Versand-Timer verwenden können, der zum Planen von Timern für Hintergrund-Threads nützlich ist. Da Dispatch-Timer blockbasiert sind, werden einige der starken Herausforderungen des Referenzzyklus mit dem alten target
/ selector
Muster von vermieden Timer
, solange Sie weak
Referenzen verwenden.
So:
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!.schedule(deadline: .now(), repeating: .seconds(60))
timer!.setEventHandler { [weak self] in
// do whatever you want here
}
timer!.resume()
}
func stopTimer() {
timer?.cancel()
timer = nil
}
deinit {
self.stopTimer()
}
Weitere Informationen finden Sie in der das Erstellen eines Timer Abschnitt Versand Quelle Beispiele in der Dispatch - Quellen Abschnitt des Concurrency Programming Guide.
Für Swift 2 siehe vorherige Überarbeitung dieser Antwort .
dispatch_after
. Oder eine sich nicht wiederholende NSTimer
.
Hier ist ein Update der NSTimer
Antwort für Swift 3 (in das NSTimer
umbenannt wurde Timer
), bei dem ein Abschluss anstelle einer benannten Funktion verwendet wird:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
Wenn Sie eine gewisse Zeitverschiebung zulassen können , finden Sie hier eine einfache Lösung, mit der jede Minute Code ausgeführt wird:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Nur executeRepeatedly()
einmal ausführen und es wird jede Minute ausgeführt. Die Ausführung wird beendet, wenn das besitzende Objekt ( self
) freigegeben wird. Sie können auch ein Flag verwenden, um anzuzeigen, dass die Ausführung gestoppt werden muss.
Sie können verwenden Timer
(schnell 3)
var timer = Timer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true)
In selector () geben Sie Ihren Funktionsnamen ein
Timer
... NSTimer
wurde umbenannt
In Swift 3.0 wurde die GCD überarbeitet:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
Dies ist besonders nützlich, wenn Sie in einer bestimmten Warteschlange versenden müssen. Wenn Sie dies für die Aktualisierung der Benutzeroberfläche verwenden möchten, sollten Sie prüfen, ob CADisplayLink
es mit der GPU-Aktualisierungsrate synchronisiert ist.