2016-07-02 14 views
8

Das folgende Code-Snippet funktioniert perfekt, wenn es außerhalb eines Completion-Blocks aufgerufen wird, aber der Timer wird nie ausgelöst, wenn ich ihn innerhalb des Blocks eingerichtet habe. Ich verstehe nicht, warum es einen Unterschied gibt:Warum sollte ein `terminatedTimer` beim Setup außerhalb eines Blocks, aber nicht innerhalb eines Blocks, ordnungsgemäß ausgelöst werden?

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

ich nicht die Selbstreferenzen verwendet wurde, wenn es anfänglich außerhalb des Blocks aufrufen, aber dann einmal im Inneren, es erforderlich war. Ich habe jedoch genau den gleichen Code außerhalb des Blocks erneut getestet und es funktioniert immer noch.

Der Block ist ein Completion-Handler, der nach dem Einholen der Berechtigung für HealthKit zugehörige Informationen aufgerufen wird.

Antwort

26

Das Problem ist, dass der fragliche Completion-Block wahrscheinlich nicht auf dem Haupt-Thread ausgeführt wurde und daher keine Lauf-Schleife hatte. Timer müssen jedoch in einer Ausführungsschleife eingeplant werden, und während der Hauptthread über einen verfügt, werden die meisten Hintergrundthreads nicht ausgeführt (es sei denn, Sie fügen einen selbst hinzu).

Um dies zu beheben, in diesem Abschluss-Handler, Versand sollte die Erstellung des Timers zurück zum Haupt-Thread und es funktioniert:

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

Oder einen Dispatch Quelle Timer (Timer verwenden, die geplant werden können für eine Hintergrundwarteschlange und erfordert keine Laufschleife).

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

Dank macht viel Sinn. Ich hätte daran denken sollen. Vielen Dank. – Kevin

Verwandte Themen