2016-07-02 18 views
8

Il seguente frammento di codice funziona perfettamente quando viene chiamato all'esterno di un blocco di completamento, ma il timer non viene mai attivato quando lo ho impostato all'interno del blocco. Non capisco il motivo per cui c'è una differenza:Perché un `scheduledTimer` dovrebbe essere attivato correttamente quando viene impostato all'esterno di un blocco, ma non all'interno di un blocco?

self.timer = Timer.scheduledTimer(timeInterval: 1, 
            target: self, 
            selector: #selector(self.foo), 
            userInfo: nil, 
            repeats: true) 

non stavo usando i riferimenti di auto al momento della chiamata inizialmente al di fuori del blocco, ma poi una volta dentro, è stato richiesto. Tuttavia ho testato di nuovo lo stesso codice esatto fuori dal blocco e funziona ancora.

Il blocco è un hander di completamento che viene chiamato dopo aver chiesto il permesso per le informazioni relative a HealthKit.

risposta

26

Il problema è che il blocco di completamento in questione probabilmente non era in esecuzione sul thread principale e quindi non aveva un ciclo di esecuzione. Ma i timer devono essere programmati su un ciclo di esecuzione e mentre il thread principale ne ha uno, la maggior parte dei thread in background non lo fanno (a meno che non ne aggiungiate uno voi stessi).

Per risolvere questo problema, in quanto gestore di completamento, la spedizione la creazione del timer torna al thread principale e dovrebbe funzionare bene:

DispatchQueue.main.async { 
    self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true) 
} 

Oppure utilizzare un timer fonte spedizione (un timer che possono essere programmati per una coda in background e non richiede un ciclo di esecuzione).

var timer: DispatchSourceTimer! 

func startTimer() { 
    let queue = DispatchQueue(label: "com.domain.app.timer") 
    timer = DispatchSource.timer(queue: queue) 
    timer.setEventHandler { [weak self] in 
     // do something 
    } 
    timer.scheduleRepeating(deadline: .now(), interval: 1.0) 
    timer.resume() 
} 
+0

Grazie ha molto senso. Avrei dovuto pensarci. Grazie. – Kevin

Problemi correlati