Blöcke statt perform: withobject: afterDelay: [Duplikat]
-
25-09-2019 - |
Frage
Diese Frage bereits eine Antwort hier:
Ich möchte oft einige Code ein paar Mikrosekunden in der Zukunft auszuführen. Gerade jetzt, ich lösen es wie folgt aus:
- (void)someMethod
{
// some code
}
Und dies:
[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];
Es funktioniert, aber ich habe eine neue Methode jedes Mal erstellen. Ist es möglich, Blöcke statt diese zu benutzen? Grundsätzlich suche ich nach einer Methode, wie:
[self performBlock:^{
// some code
} afterDelay:0.1];
Das wäre mir wirklich nützlich sein.
Lösung
Es gibt kein integrierte Möglichkeit, das zu tun, aber es ist nicht so schlecht über eine Kategorie hinzuzufügen:
@implementation NSObject (PerformBlockAfterDelay)
- (void)performBlock:(void (^)(void))block
afterDelay:(NSTimeInterval)delay
{
block = [[block copy] autorelease];
[self performSelector:@selector(fireBlockAfterDelay:)
withObject:block
afterDelay:delay];
}
- (void)fireBlockAfterDelay:(void (^)(void))block {
block();
}
@end
Kredit an Mike Ash für den Grund Umsetzung.
Andere Tipps
Hier ist eine einfache Technik, basierend auf GCD, dass ich mit:
void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
dispatch_get_current_queue(), block);
}
Ich bin kein GCD-Experte, und ich würde in Kommentaren zu dieser Lösung interessiert sein.
Eine andere Möglichkeit (vielleicht der schlechteste Weg, dies aus vielen Gründen zu tun) ist:
[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
//do stuff here
}];
Wenn Sie speziell eine längere Verzögerung benötigen, die Lösungen über gut funktionieren. Ich habe verwendet @ nick Ansatz mit großem Erfolg.
Wenn Sie jedoch nur ein Baustein, der während der nächsten Iteration der Hauptschleife zu laufen, können Sie sie trimmen noch weiter nach unten nur mit den folgenden:
[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];
Das ist vergleichbar mit mit perform: mit afterDelay von 0.0f
Ich habe einen ähnlichen Code wie folgt aus:
double delayInSeconds = 0.2f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//whatever you wanted to do here...
});
Es gibt eine schöne, komplette Kategorie, dass Griffe diese Situation hier: