我有以下情况:
dispatch_after_delta(0.1, ^{
[self checkForTodaysBonus]; // It contains animation methods.
});
并且
-(void) checkForTodaysBonus {
// Prepare View and other data and then animate UIView
[Animations moveDown:self.view andAnimationDuration:0.3 andWait:YES andLength:self.view.frame.size.height];
}
其中,moveDown方法如下:
+ (void) moveDown: (UIView *)view andAnimationDuration: (float) duration andWait:(BOOL) wait andLength:(float) length{
__block BOOL done = wait; //wait = YES wait to finish animation
[UIView animateWithDuration:duration animations:^{
view.center = CGPointMake(view.center.x, view.center.y + length);
} completion:^(BOOL finished) {
// This never happens if I call this method from dispatch_after.
done = NO;
}];
// wait for animation to finish
// This loop will allow wait to complete animation
while (done == YES) { // Application unable to break this condition
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
}
和
void dispatch_after_delta(float delta, dispatch_block_t block){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta * NSEC_PER_SEC), dispatch_get_main_queue(), block);
}
所以,问题,只要从animation
,dispatch_after_delta
方法animation
调用never gets its completion block
方法。
什么是可能的解决方案?
答案 0 :(得分:0)
我给你的建议是使用performSelector: withObject: afterDelay:
。
将当前的dispatch_after替换为:
[self performSelector:@selector(checkForTodaysBonus) withObject:nil afterDelay:1.0f];
答案 1 :(得分:0)
比因为你提交了块
^{
[self checkForTodaysBonus]; // It contains animation methods.
});
到主队列,主队列是一个串行队列,因此动画完成块不会执行,直到上面的块返回。
要解决此问题,您可以:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta * NSEC_PER_SEC),
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), block);
在主队列中执行动画:
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:duration animations:^{
view.center = CGPointMake(view.center.x, view.center.y + length);
} completion:^(BOOL finished) {
// This never happens if I call this method from dispatch_after.
done = NO;
}];
});
在我看来,您最好不要在调度块中明确使用NSThread和NSRunLoop。