@zaph eine ziemlich gute Lösung. Ich dachte, ich würde es aus einem anderen Blickwinkel versuchen. Da Objective-C Ziel -C ist, warum nicht eine Art von Objekt definieren, dies zu tun timed Looping? Tipp: Das existiert. Wir können NSTimer und seine userInfo-Eigenschaft verwenden, um dies auszuarbeiten. Ich denke, die Lösung ist eine Art eleganter, wenn nicht ein hässlicher Hack.
// Somewhere in code.... to start the 'loop'
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
action:@selector(processNextTransaction:)
userInfo:@{
@"gains": [gainsArray mutableCopy]
}
repeats:NO];
// What handles each 'iteration' of your 'loop'
- (void)processNextTransaction:(NSTimer *)loopTimer {
NSMutableArray *gains = [loopTimer.userInfo objectForKey:@"gains"];
if(gains && gains.count > 0) {
id transaction = [gains firstObject];
[gains removeObjectAtIndex:0]; // NSMutableArray should really return the object we're removing, but it doesn't...
[self private_addTransactionToBankroll:transaction];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
action:@selector(processNextTransaction:)
userInfo:@{
@"gains": gains
}
repeats:NO];
}
}
Ich würde überprüfen, dass der NSTimer beibehalten wird, indem der Run-Loop hinzugefügt wird. Wenn dies nicht der Fall ist, sollten Sie einen Verweis darauf als Eigenschaft für jede Klasse speichern, die all dies verwaltet.
Es ist auch erwähnenswert, dass, weil NSTimers auf dem Hauptlaufschleife standardmäßig installiert werden, müssen Sie sich keine Gedanken über all die GCD Sachen kümmern. Dann wieder, wenn diese Arbeit ziemlich schwierige Arbeit ist, können Sie -processNextTransaction:
wollen ihre Arbeit auf eine andere GCD Warteschlange abzuladen und dann in die Hauptwarteschlange wieder auf die NSTimer Instanz zu initialisieren.
Verwenden Sie unbedingt die -scheduledTimer...
Methode; timer...
Klassenmethoden auf NSTimer
installieren Sie es nicht auf einer beliebigen Schleife, und die Objekte sitzen nur im Raum nichts zu tun. Nicht repeats:YES
tun, das wäre tragisch, wie Sie auf die Laufschleife nolens volens, angebracht Timer haben würde, um sie mit keine Hinweise Hinweis zu wissen, wie oder wo sie zu stoppen. Das ist generell eine schlechte Sache.
Um EXC_BAD_ACCESS
Ausnahmen zu vermeiden, das Objekt niemals freigeben, dessen Methode NSTimer
aufrufen wird, wenn dieser Timer noch nicht ausgelöst wurde. Möglicherweise möchten Sie die ausstehende NSTimer
in einer Eigenschaft in Ihrer Klasse speichern, so dass Sie mit dieser Art von Sache umgehen können. Wenn es ein ViewController ist, der all dies verwaltet (was es normalerweise ist), würde ich den folgenden Code verwenden, um den Timer auf -viewWillDisappear
zu bereinigen. (Dies setzt voraus, dass Sie einen neuen Timer zu einem gewissen @property
sind Einstellung, self.timer
)
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if(self.timer) {
[self.timer invalidate]; // -invalidate removes it from the run loop.
self.timer = nil; // Stop pointing at it so ARC destroys it.
}
}
eine 'NSTimer' Verwendung ist auch eine gute Lösung. – zaph
@zaph NSTimer spielt nicht gut mit cocos2d oder SpriteKit. Bevorzugen Sie die eingebauten 'Schedule'-Methoden, die von CCNode und all seinen abgeleiteten Klassen bereitgestellt werden. – YvesLeBorg