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")
}
NSTimer
mantiene il suo obiettivo, quindi, con questa configurazione, se helloWorldTimer
è una proprietà su self
hai un ciclo di conservazione, dove self
trattiene helloWorldTimer
e helloWorldTimer
trattiene 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 Timer
sia 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.selector
Timer
weak
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 NSTimer
risposta, per Swift 3 (in cui è NSTimer
stato 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 self
viene 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 CADisplayLink
poiché è sincronizzato con la frequenza di aggiornamento della GPU.