Odpowiedzi:
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
Pamiętaj, aby zaimportować 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
zachowuje swój cel, więc przy tej konfiguracji, jeśli helloWorldTimer
jest to właściwość self
, masz cykl utrzymania, w którym self
zachowuje helloWorldTimer
i helloWorldTimer
zachowuje self
.
Jeśli celujesz w system iOS w wersji 10 lub nowszej, możesz użyć wersji opartej na blokach Timer
, co upraszcza potencjalne silne cykle odwołań, np .:
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()
}
Chociaż Timer
ogólnie jest to najlepsze, ze względu na kompletność należy zauważyć, że można również użyć licznika czasu wysyłki, który jest przydatny do planowania liczników czasu w wątkach w tle. Dzięki zegarom wysyłkowym, ponieważ są one oparte na blokach, unika się niektórych silnych wyzwań cyklu referencyjnego ze starym wzorcem target
/ , o ile używasz odwołań.selector
Timer
weak
Więc:
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()
}
Aby uzyskać więcej informacji, zobacz The Tworzenie timera odcinek Wysłanie źródłowe przykładów w dyspozytorskie Sources sekcji Programowanie Współbieżnym Guide.
W przypadku Swift 2 zobacz poprzednią wersję tej odpowiedzi .
dispatch_after
. Lub niepowtarzalny NSTimer
.
Oto aktualizacja NSTimer
odpowiedzi dla języka Swift 3 (w którym NSTimer
zmieniono nazwę na Timer
) przy użyciu zamknięcia zamiast nazwanej funkcji:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
Jeśli możesz pozwolić sobie na dryf w czasie, oto proste rozwiązanie wykonujące jakiś kod co minutę:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Po prostu uruchom executeRepeatedly()
raz i będzie wykonywane co minutę. Wykonywanie zatrzymuje się po self
zwolnieniu obiektu będącego właścicielem ( ). Możesz również użyć flagi, aby wskazać, że wykonanie musi zostać zatrzymane.
W swift 3.0 GCD został refaktoryzowany:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
Jest to szczególnie przydatne, gdy chcesz wysłać wiadomość w określonej kolejce. Ponadto, jeśli planujesz używać tego do aktualizacji interfejsu użytkownika, sugeruję sprawdzenie, CADisplayLink
czy jest zsynchronizowany z częstotliwością odświeżania GPU.