Risposte:
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
Ricorda di importare Foundation.
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")
}
NSTimermantiene il suo obiettivo, quindi, con questa configurazione, se helloWorldTimerè una proprietà su selfhai un ciclo di conservazione, dove selftrattiene helloWorldTimere helloWorldTimertrattiene self.
Se scegli come target iOS versione 10 e successive, puoi utilizzare la resa basata su blocchi di Timer, che semplifica i potenziali cicli di riferimento forti, ad esempio:
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()
}
Sebbene Timersia generalmente il migliore, per ragioni di completezza, dovrei notare che puoi anche usare il timer di invio, che è utile per programmare i timer sui thread in background. Con i timer di invio, poiché sono basati su blocchi, evita alcune delle forti sfide del ciclo di riferimento con il vecchio modello target/ , purché utilizzi i riferimenti.selectorTimerweak
Così:
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()
}
Per ulteriori informazioni, vedere la sezione Creazione di un timer di Esempi di origini di invio nella sezione Origini di invio della Guida alla programmazione della concorrenza.
Per Swift 2, vedere la revisione precedente di questa risposta .
dispatch_after. O un non ripetitivo NSTimer.
Ecco un aggiornamento alla NSTimerrisposta, per Swift 3 (in cui è NSTimerstato rinominato in Timer) utilizzando una chiusura anziché una funzione denominata:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
Se puoi consentire un po 'di tempo, ecco una semplice soluzione eseguendo del codice ogni minuto:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Esegui solo executeRepeatedly()una volta e verrà eseguito ogni minuto. L'esecuzione si interrompe quando selfviene rilasciato l'oggetto proprietario ( ). È inoltre possibile utilizzare un flag per indicare che l'esecuzione deve essere interrotta.
In swift 3.0 il GCD è stato refactoring:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
Ciò è particolarmente utile quando è necessario eseguire l'invio su una particolare coda. Inoltre, se hai intenzione di utilizzarlo per l'aggiornamento dell'interfaccia utente, ti suggerisco di controllare CADisplayLinkpoiché è sincronizzato con la frequenza di aggiornamento della GPU.