ios - community - swift apple download
Haz algo cada x minutos en Swift (6)
Aquí hay una actualización de la respuesta
NSTimer
, para Swift 3 (en la que
NSTimer
fue renombrado a
Timer
) usando un cierre en lugar de una función con nombre:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
(_) in
print("Hello world")
}
¿Cómo puedo ejecutar una función cada minuto?
En JavaScript puedo hacer algo como
setInterval
, ¿existe algo similar en Swift?
Salida deseada:
Hola mundo una vez por minuto ...
En Swift 3, puede crear un
Timer
.
Y si apunta a iOS versión 10 y superior, puede usar la representación basada en bloques, que simplifica los potenciales ciclos de referencia fuertes, por ejemplo:
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()
}
En Swift 2, crea un
NSTimer
.
Y si está usando Swift 2, es posible que esté usando la versión de iOS anterior a la 10.0, en cuyo caso debe usar el patrón de
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()
}
Si bien
NSTimer
es generalmente el mejor, en aras de la exhaustividad, debo tener en cuenta que también puede usar el temporizador de envío, que es útil para programar temporizadores en subprocesos en segundo plano.
Con los temporizadores de despacho, dado que están basados en bloques, evita algunos de los fuertes desafíos del ciclo de referencia con el antiguo patrón de
target
/
selector
de
NSTimer
, siempre que use referencias
weak
.
Entonces, en 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()
}
En 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()
}
Para obtener más información, consulte la sección Creación de un temporizador de Ejemplos de fuentes de envío en la sección Fuentes de envío de la Guía de programación de concurrencia.
En swift 3.0, el GCD se refactorizó:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
NSLog("Hello World")
}
timer.resume()
Esto es especialmente útil para cuando necesita despachar en una cola particular.
Además, si planea usar esto para actualizar la interfaz de usuario, le sugiero que busque
CADisplayLink
ya que está sincronizado con la frecuencia de actualización de la GPU.
Puedes usar
NSTimer
var timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("function"), userInfo: nil, repeats: true)
En selector () pones el nombre de tu función
Si puede esperar un poco de tiempo, aquí hay una solución simple que ejecuta un código cada minuto:
private func executeRepeatedly() {
// put your code here
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
self?.executeRepeatedly()
}
}
Simplemente ejecute
executeRepeatedly()
una vez y se ejecutará cada minuto.
La ejecución se detiene cuando se libera el objeto propietario (
self
).
También puede usar una bandera para indicar que la ejecución debe detenerse.
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello()
{
NSLog("hello World")
}
Recuerde importar la Fundación.
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")
}