Erstellen einer Methode zum Ausführen von Animationen und zum Warten auf den Abschluss mithilfe eines Semaphors in Ziel c

Ich versuche, eine Methode zu erstellen, die die UIView-Methode "+ animateWithDuration: animations: completion" verwendet, um Animationen auszuführen und auf den Abschluss zu warten. Ich bin mir durchaus bewusst, dass ich den Code, der normalerweise danach kommt, einfach in einen Abschlussblock einfügen könnte, aber ich möchte dies vermeiden, da er eine erhebliche Menge Code enthält, der weitere Animationen enthält, wodurch ich verschachtelte Blöcke hätte .

Ich habe versucht, diese Methode wie folgt mit einem Semaphor zu implementieren, aber ich denke nicht, dass dies der beste Weg ist, um es zu tun, vor allem, weil es nicht wirklich funktioniert. Kann mir jemand sagen, was mit meinem Code nicht stimmt und / oder wie ich das gleiche Ziel am besten erreichen kann?

+(void)animateAndWaitForCompletionWithDuration:(NSTimeInterval)duration animations:(void  (^)(void))animations
{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    [UIView animateWithDuration:duration
                 animations:animations
                 completion:^(BOOL finished) {
                     dispatch_semaphore_signal(semaphore);
                 }];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}

Ich bin mir nicht sicher, was mit meinem Code nicht stimmt, aber wenn ich die unten gezeigte Methode aufrufe, wird der Completion-Block nie ausgeführt und ich gerate in die Schwebe.

[Foo animateAndWaitForCompletionWithDuration:0.5 animations:^{
    //do stuff
}];

-------------------------------------------BEARBEITEN------ -------------------------------------------

Wenn jemand ein ähnliches Problem hat, könnte es Sie interessieren, welchen Code ich verwendet habe. Es nutzt die Rekursion, um jeden Abschlussblock zu nutzen, ohne jeden Funktionsaufruf verschachteln zu müssen.

+(void)animateBlocks:(NSArray*)animations withDurations:(NSArray*)durations {
    [Foo animateBlocks:animations withDurations:durations atIndex:0];
}

+(void)animateBlocks:(NSArray*)animations withDurations:(NSArray*)durations atIndex:(NSUInteger)i {
    if (i < [animations count] && i < [durations count]) {
         [UIView animateWithDuration:[(NSNumber*)durations[i] floatValue]
                          animations:(void(^)(void))animations[i]
                          completion:^(BOOL finished){
             [Foo animateBlocks:animations withDurations:durations atIndex:i+1];
         }];
    } 
}

die kann so verwendet werden

[Foo animateBlocks:@[^{/*first animation*/},
                     ^{/*second animation*/}]
     withDurations:@[[NSNumber numberWithFloat:2.0],
                     [NSNumber numberWithFloat:2.0]]];

Antworten auf die Frage(5)

Ihre Antwort auf die Frage