2015-01-22 4 views
24

Gibt es eine Möglichkeit, dispatch_after() für einige Zeit in Zukunft geplant, und bisher nicht gefeuert? Ich versuche, etwas wie ein Scheduler für Updates vom Server zu machen, und diese Methode ist genau wie ich will, aber ich würde es gerne irgendwann abbrechen und neu planen. Ist es überhaupt möglich oder muss ich zurückfallen und NSTimer verwenden?abbrechen dispatch_after() Methode?

+0

yup. scheint, als ob wir Duplikate haben. Frage mich, ob es möglich ist, diese Fragen zusammenzuführen? –

Antwort

1

Verwenden Sie eine Dispatch-Timer-Quelle (das wird dispatch_after ohnehin intern verwendet).

Eine Sende-Timer-Quelle kann abgebrochen oder ihre Timer-Parameter nach der Erstellung geändert werden.

19

Es gibt KEINE Möglichkeit zu verhindern, dass ein dispatch_block ausgeführt wird, sobald er in seine Warteschlange gesendet wurde, was bedeutet, dass Ihre dispatch_after nicht storniert werden kann. Die einzige Option besteht darin, in Ihrem Block eine Bedingung hinzuzufügen, die zur Laufzeit überprüft werden muss, um die Ausführung zu verhindern. dh.

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), dispatch_get_main_queue(),^{ 
if(self.shouldExecuteDispatchBlock) 
{ // do your stuff } }); 
+0

Hmmm, bis das nächste Mal für die Ausführung dieses Blocks auftaucht (und es eingestellt ist, abgebrochen zu werden), ich denke, es würde bis dahin alle Speicher/Objekte hog. Vielleicht ein Problem, wenn Ihre Zyklen wie 60 Minuten sind? :-) – Jonny

+0

Ja und nein. Der Block kopiert den Speicher, was bedeutet, dass wenn Sie auf einen int-Wert in Ihrem Block verweisen, dieser kopiert wird und solange als Block für den Block im Speicher verbleibt. Aber für Objekt, es kopiert sie nicht, es kopiert die Adresse. Wenn Sie ein Bild referenzieren, haben Sie ein UIImage-Objekt im Heap, aber der Block behält nur einen Zeigerwert (8 Bytes in arch64), also kein großes Problem. Natürlich wird das Bild im Speicher behalten, bis der Block erlischt, so dass es nicht durch einen Bogen sauber wird. –

+0

Ich habe dies in eine Erweiterung für DispatchQueue verwandelt: https://github.com/nrbrook/DispatchAfterCancellable – Nick

11

OK, also mit allen Antworten gesammelt und möglichen Lösungen, scheint die besten für diesen Fall (Erhaltung Einfachheit) rufe performSelector:withObject:afterDelay: und es mit cancelPreviousPerformRequestsWithTarget: Ruf, wenn gewünscht. In meinem Fall - kurz vor dem nächsten verzögerte Anrufplanung:

[NSObject cancelPreviousPerformRequestsWithTarget: self selector:@selector(myDelayedMethod) object: self]; 

[self performSelector:@selector(myDelayedMethod) withObject: self afterDelay: desiredDelay]; 
+0

Ich habe diesen Pfad gestartet, aber wie macht man das mit Klassenmethoden (weshalb ich zu "dispatch_after" gewechselt habe)? – Olie

+0

@Olie gut eins. Dann müssen Sie diese Anrufe in Instanz umhüllen, oder verwenden Sie Versand + Flag (raten, zweitens wäre einfacher) –

Verwandte Themen