Ihre for
Schleife wird fast sofort durch die gesamte Sequenz iterieren, was bedeutet, dass Ihre inneren dispatch_after
Anrufe werden fast zur gleichen Zeit eingestellt, und so wird etwa zur gleichen Zeit, die Sie sehen, ausgeführt werden.
Sie würden wahrscheinlich in diesem Fall mit einer NSTimer
besser bedient werden. Etwas wie folgt aus:
Eine NSTimer
Eigenschaft zu verwenden:
@property (strong) NSTimer* deletionTimer = nil;
diese Methoden Ihrer Klasse hinzufügen:
- (void)startDeletionTimer {
[self killDeletionTimer];
self.deletionTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(deletionTimerFired:) userInfo:nil repeats:YES];
}
- (void)killDeletionTimer {
[self.deletionTimer invalidate];
self.deletionTimer = nil;
}
- (void)deletionTimerFired:(NSTimer*)timer {
NSUInteger numberOfRecords = [array_messages count];
if (!numberOfRecords) {
// None left, we're done
[self killDeleteionTimer];
return;
}
[array_messages removeObjectAtIndex:0];
[self.tableViewMessage deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationTop];
}
einleiten Timer mit diesem:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self startDeletionTimer];
});
Diese hat einige Vorteile gegenüber Optionen mit dem inneren dispatch_after
mit einer Verzögerung. Es wird gnädig Änderungen im array_messages
Array handhaben, da seine Zählung bei jeder Iteration überprüft wird, nicht am Anfang angenommen. Wenn Sie zum Beispiel 30 Nachrichten haben, dauert Ihr gesamter Löschvorgang 30 Sekunden. Wenn eine neue Nachricht in diesem Zeitraum hinzugefügt wird, oder schlimmer noch, eine Nachricht wird irgendwie entfernt, stürzt Ihre App ab, wenn die letzte dispatch_after
auslöst, da der Index und/oder die Zeile nicht existiert. Ähnlich verhält es sich, wenn der Benutzer von der Ansicht weg navigiert, kann die Tabellensicht aufgehoben werden und Sie werden dann abstürzen.
Ein weiterer Vorteil ist, wenn in diesen 30 Sekunden, während es langsam/schmerzhaft zeigt die Datensätze gelöscht werden, der Benutzer nur weitergehen will, können Sie den Timer beenden und löschen Sie einfach alle Zeilen auf einmal.
Warum sollten sie nicht? Sie versenden seriell, aber ohne Verzögerung zwischen den Versendungen. Sie müssen es rekursiv machen - jeden Dispatch-Block den nächsten Löschvorgang veranlassen. – Avi
Ich bestätige das. Nach der Verwendung von Grand Central Dispatch für Jahre und Jahre muss ich sagen, dass GCD viele Probleme hat. Abhängig von der Art des Codes, den Sie entwickeln, funktionieren GCD-Mechanismen einfach nicht wie erwartet. Ich musste heute einen Code ersetzen, wo ein Block gefeuert wurde, gefolgt von einem dispatch_after-Code, um den Vorgang Sekunden später abzubrechen, weil das Ganze nicht auf iPhone 5 funktionierte. Derselbe Code funktionierte perfekt auf iPhone 6. Beide unter iOS 9.3. 2. Auf dem iPhone 5 wurde die Nachricht "dispatch_after" vor der angegebenen Zeit ausgelöst.Ich empfehle stattdessen NSOperationQueue zu verwenden. – SpaceDog