Ответы:
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
Не забудьте импортировать 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
это сохраняет свою цель, поэтому с этой настройкой, если helloWorldTimer
это свойство self
, у вас есть цикл сохранения, в котором self
сохраняется helloWorldTimer
и helloWorldTimer
сохраняется self
.
Если нацелена на iOS версии 10 и выше, вы можете использовать блочное представление Timer
, что упрощает потенциальные циклы сильных ссылок, например:
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()
}
Хотя Timer
в целом это лучше, для полноты картины я должен отметить, что вы также можете использовать таймер отправки, который полезен для планирования таймеров в фоновых потоках. С таймерами отправки, поскольку они основаны на блоках, они позволяют избежать некоторых проблем с сильным ссылочным циклом со старым target
/ selector
шаблономTimer
, если вы используете weak
ссылки.
Так:
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()
}
Для получения дополнительной информации см Создание таймера раздел Отправка Источник примеров в источниках отправки секции параллелизмом Руководство по программированию.
Для Swift 2 см. Предыдущую версию этого ответа .
dispatch_after
. Или неповторяющийся NSTimer
.
Вот обновление NSTimer
ответа для Swift 3 (в котором NSTimer
был переименован в Timer
) с использованием замыкания, а не именованной функции:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
Если вы можете позволить себе некоторое время дрейфовать, вот простое решение, выполняющее некоторый код каждую минуту:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Просто запустите executeRepeatedly()
один раз, и он будет выполняться каждую минуту. Выполнение останавливается, когда объект-владелец ( self
) освобождается. Вы также можете использовать флаг, чтобы указать, что выполнение должно быть остановлено.
В Swift 3.0 был произведен рефакторинг GCD:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
Это особенно полезно, когда вам нужно выполнить отправку в определенной очереди. Кроме того, если вы планируете использовать это для обновления пользовательского интерфейса, я предлагаю проверить CADisplayLink
, синхронизируется ли он с частотой обновления графического процессора.