Как я могу запускать функцию каждую минуту?
В JavaScript я могу сделать что-то вроде setInterval
, что-то подобное существует в Swift?
Требуемый вывод:
Привет мир раз в минуту...
Как я могу запускать функцию каждую минуту?
В JavaScript я могу сделать что-то вроде setInterval
, что-то подобное существует в Swift?
Требуемый вывод:
Привет мир раз в минуту...
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")
}
В Swift 3 вы можете создать Timer
. И, если вы используете таргетинг на iOS версии 10 и выше, вы можете использовать разметку на основе блоков, что упрощает потенциальные сильные ссылочные циклы, например:
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()
}
В Swift 2 вы создаете NSTimer
. И если вы используете Swift 2, вы можете использовать версию iOS до 10.0, и в этом случае вам придется использовать более старый шаблон target
/selector
:
weak var timer: NSTimer?
func startTimer() {
timer?.invalidate() // just in case you had existing `NSTimer`, `invalidate` it before we lose our reference to it
timer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)
}
func handleTimer(timer: NSTimer) {
// do something here
}
func stopTimer() {
timer?.invalidate()
}
// because this old target/selector approach will keep a strong reference
// to the `target`, if you want the timer to stop when the view controller
// is dismissed, you can't stop the timer in `deinit`, but rather have to
// detect the dismissing of the view controller using other mechanisms. Commonly,
// we used to detect the view disappearing, like below:
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
stopTimer()
}
Хотя NSTimer
, как правило, лучше всего, для полноты, я должен отметить, что вы также можете использовать таймер отправки, который полезен для планирования таймеров по фоновым потокам. При отправке таймеров, так как они на основе блоков, это позволяет избежать некоторых сильных проблем опорного цикла со старым target
/<Т24 > модель NSTimer
, до тех пор, пока вы используете weak
ссылки.Р >
Итак, в Swift 3:
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!.scheduleRepeating(deadline: .now(), interval: .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:
var timer: dispatch_source_t?
func startTimer() {
let queue = dispatch_queue_create("com.domain.app.timer", nil) // again, you can use `dispatch_get_main_queue()` if you want to use the main queue
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)
dispatch_source_set_timer(timer!, DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC, 1 * NSEC_PER_SEC) // every 60 seconds, with leeway of 1 second
dispatch_source_set_event_handler(timer!) { [weak self] in
// do whatever you want here
}
dispatch_resume(timer!)
}
func stopTimer() {
if let timer = timer {
dispatch_source_cancel(timer)
self.timer = nil
}
}
deinit {
self.stopTimer()
}
Дополнительные сведения см. в разделе "Создание таймера" в примерах источника отправки в разделе Отладочные файлы в руководстве по программированию Concurrency.
Здесь обновление для ответа NSTimer
для Swift 3 (в котором NSTimer
было переименовано в Timer
), используя закрытие, а не именованную функцию:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
Вы можете использовать NSTimer
var timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true)
В селекторе() вы введете имя своей функции
В 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
, поскольку он синхронизирован с частотой обновления GPU.
Если вы можете позволить себе некоторое время дрейфа здесь простое решение, выполняющее какой-то код каждую минуту:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Просто запустите executeRepeatedly()
один раз, и он будет выполняться каждую минуту. Выполнение прекращается, когда освобождается объект-владелец (self
). Вы также можете использовать флаг, указывающий, что выполнение должно быть остановлено.