Wprowadzam pasek zdrowia, który animuje się za pomocą danych wprowadzanych przez użytkownika.Jak wykonać blokadę, która czeka aż animacja się zakończy?
Te animacje powodują zwiększenie lub zmniejszenie o określoną wartość (na przykład 50 jednostek) i są wynikiem naciśnięcia przycisku. Są dwa przyciski. Zwiększ i zmniejsz.
Chcę wykonać blokadę na pasku stanu, tak aby tylko jeden wątek mógł ją zmienić jednocześnie. Problem polega na tym, że dostaję impasu.
Zgaduję, ponieważ oddzielny wątek uruchamia blokadę, która jest utrzymywana przez inny wątek. Ale ta blokada ustąpi po zakończeniu animacji. Jak zaimplementować blokadę, która kończy się po zakończeniu [UIView AnimateWithDuration]?
Zastanawiam się, czy jest to możliwe, aby przejść na NSConditionLock
, ale jeśli to możliwe, chcę użyć NSLocks, aby uniknąć niepotrzebnej złożoności. Co polecasz?
(W końcu chcę mieć animacje „kolejce”, podczas gdy pozwalając wejście użytkownik nadal, ale teraz po prostu chcę, aby uzyskać blokadę pracy, nawet jeśli wejście blokuje pierwszy).
(Hmm przyjść do myślę o tym, że jest tylko jedna [UIView AnimateWithDuration] działająca w tym samym czasie dla tego samego UIView. Drugie wywołanie przerywa pierwszą, powodując, że procedura zakończenia zostanie uruchomiona natychmiast dla pierwszego. Może druga blokada działa, zanim pierwsza ma szansę aby odblokować Jaki jest najlepszy sposób na zablokowanie w tym przypadku? Być może powinienem ponownie odwiedzić Grand Central Dispatch, ale chciałem sprawdzić, czy był prostszy sposób.)
W ViewController.h Deklaruję:
NSLock *_lock;
W ViewController.m mam:
W loadview:
_lock = [[NSLock alloc] init];
Reszta ViewController.m (istotne części):
-(void)tryTheLockWithStr:(NSString *)str
{
LLog(@"\n");
LLog(@" tryTheLock %@..", str);
if ([_lock tryLock] == NO)
{
NSLog(@"LOCKED.");
}
else
{
NSLog(@"free.");
[_lock unlock];
}
}
// TOUCH DECREASE BUTTON
-(void)touchThreadButton1
{
LLog(@" touchThreadButton1..");
[self tryTheLockWithStr:@"beforeLock"];
[_lock lock];
[self tryTheLockWithStr:@"afterLock"];
int changeAmtInt = ((-1) * FILLBAR_CHANGE_AMT);
[self updateFillBar1Value:changeAmtInt];
[UIView animateWithDuration:1.0
delay:0.0
options:(UIViewAnimationOptionTransitionNone|UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionAllowUserInteraction)
animations:
^{
LLog(@" BEGIN animationBlock - val: %d", self.fillBar1Value)
self.fillBar1.frame = CGRectMake(FILLBAR_1_X_ORIGIN,FILLBAR_1_Y_ORIGIN, self.fillBar1Value,30);
}
completion:^(BOOL finished)
{
LLog(@" END animationBlock - val: %d - finished: %@", self.fillBar1Value, (finished ? @"YES" : @"NO"));
[self tryTheLockWithStr:@"beforeUnlock"];
[_lock unlock];
[self tryTheLockWithStr:@"afterUnlock"];
}
];
}
-(void)updateFillBar1Value:(int)changeAmt
{
self.prevFillBar1Value = self.fillBar1Value;
self.fillBar1Value += changeAmt;
if (self.fillBar1Value < FILLBAR_MIN_VALUE)
{
self.fillBar1Value = FILLBAR_MIN_VALUE;
}
else if (self.fillBar1Value > FILLBAR_MAX_VALUE)
{
self.fillBar1Value = FILLBAR_MAX_VALUE;
}
}
wyjściowa:
To-odtworzenia Instrukcje: Wybierz "Zmniejsz" raz
touchThreadButton1 ..
tryTheLock beforeLock .. darmo.
tryTheLock afterLock .. ZABLOKOWANE. BEGIN animationBlock - Val: 250 END animationBlock - Val: 250 - Ukończony TAK
tryTheLock beforeUnlock .. zablokowana.
tryTheLock afterUnlock .. za darmo.
Wniosek: Działa to zgodnie z oczekiwaniami.
-
wyjściowa:
To-odtworzenia Instrukcje: Wybierz "Zmniejsz" dwa razy szybko (przerywa początkową animację) ..
touchThreadButton1 ..
tryTheLock beforeLock .. za darmo.
tryTheLock afterLock .. ZABLOKOWANE. UŻYCIEM animationBlock - val 250 touchThreadButton1 ..
tryTheLock beforeLock .. zablokowane. * - [Blokada NSLock]: zakleszczenie ('(null)') * Przerwij _NSLockError() do debugowania.
Podsumowanie. Błąd impasu. Wprowadzane przez użytkownika jest zamrożone.
Dziękuję, proszę pana! Doceniam sposób, w jaki demonstrujesz NSOperationQueue w jasny sposób. Zamknięcie operacji wielkości w jej własnej klasie jest raczej eleganckie. Działa idealnie. –
@BlackOrchid FYI, Jestem pewien, że już dawno temu minęło to pytanie, ale zaktualizowałem je o znacznie prostsze podejście. – Rob
Chciałbym móc to zrobić więcej niż raz. :) –