Réponses:
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
N'oubliez pas d'importer 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
conserve sa cible, donc, avec cette configuration, s'il helloWorldTimer
s'agit d'une propriété, self
vous avez vous-même un cycle de conservation, où self
conserve helloWorldTimer
et helloWorldTimer
conserve self
.
Si vous ciblez iOS version 10 et supérieure, vous pouvez utiliser le rendu basé sur des blocs Timer
, ce qui simplifie les cycles de référence potentiels forts, par exemple:
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()
}
Bien que ce Timer
soit généralement le meilleur, par souci d'exhaustivité, je dois noter que vous pouvez également utiliser la minuterie de répartition, ce qui est utile pour planifier des minuteries sur les threads d'arrière-plan. Avec les temporisateurs de répartition, puisqu'ils sont basés sur des blocs, cela évite certains des défis forts du cycle de référence avec l'ancien target
/ selector
modèle de Timer
, tant que vous utilisez des weak
références.
Alors:
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()
}
Pour plus d'informations, consultez la section Création d'un minuteur des exemples de sources de répartition dans la section Sources de répartition du Guide de programmation d'accès concurrentiel.
Pour Swift 2, voir la révision précédente de cette réponse .
dispatch_after
. Ou un non-répétitif NSTimer
.
Voici une mise à jour de la NSTimer
réponse, pour Swift 3 (dans lequel a NSTimer
été renommé en Timer
) en utilisant une fermeture plutôt qu'une fonction nommée:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
Si vous pouvez permettre une dérive temporelle, voici une solution simple exécutant du code toutes les minutes:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Exécutez juste executeRepeatedly()
une fois et il sera exécuté chaque minute. L'exécution s'arrête lorsque l'objet propriétaire ( self
) est libéré. Vous pouvez également utiliser un indicateur pour indiquer que l'exécution doit s'arrêter.
Vous pouvez utiliser Timer
(swift 3)
var timer = Timer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true)
Dans selector () vous mettez le nom de votre fonction
Timer
... NSTimer
a été renommé
Dans Swift 3.0, le GCD a été remanié:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
Ceci est particulièrement utile lorsque vous devez distribuer sur une file d'attente particulière. De plus, si vous prévoyez de l'utiliser pour la mise à jour de l'interface utilisateur, je vous suggère de l'examiner CADisplayLink
car il est synchronisé avec le taux de rafraîchissement du GPU.