dispatch_after 和 [UIView animation: duration] 立即发生(但不应该)
Posted
技术标签:
【中文标题】dispatch_after 和 [UIView animation: duration] 立即发生(但不应该)【英文标题】:dispatch_after and [UIView animation: duration] happen immediately (but shouldn't) 【发布时间】:2013-10-01 00:25:47 【问题描述】:在 ios7 中,我们遇到了一个间歇性错误。 iOS6 没有发生这种情况。
它不会立即开始,而是进入游戏约 30 秒到约 2 分钟,所有动画和 dispatch_after 命令都会立即发生。
更具体地说,动画正在发生,就好像“持续时间:”值是 0,即使它绝对不是 0。 更具体地说,dispatch_after 就像 wait = 0 一样发生。
一旦启动,它就会一直持续到软件终止。
我不知道如何调试它,或者它是否是 iOS7 错误。任何想法/帮助将不胜感激!
【问题讨论】:
你应该显示一些代码 我也有同样的问题。它似乎只在大约 5 分钟的游戏后才会发生,到目前为止我只能在运行 iOS7 的 iPad2 上重现它。当应用程序的 RAM 达到 80MB(iPad2 有 256 个)时,通常会发生这种情况。这最初让我印象深刻,因为它使用了大量的内存。似乎我使用的所有图像都缓存在内存中(即使它们不再出现在屏幕上并且没有对它们进行引用——例如没有内存泄漏)。我将尝试减少应用程序的内存占用,看看是否有帮助。 我有一个视图网格,一个手势会触发一个动画,该动画会改变每个视图的背景颜色,动画之间有一个常数。大约 30 次迭代后,动画开始同时发生。首先,两个动画会同时触发,然后是几个动画,3 个动画会同时触发,以此类推。但!如果手势触发另一轮,则开始执行一组新动画,并且之前尚未触发的动画再次开始运行。 我想知道这是否是某种没有经过深思熟虑的优化,还是 GCD 调度的瓶颈。您使用的是 Core Animation API 还是 UIView 动画 API?我正在使用 UIView 和 GCD。 也许有帮助:***.com/questions/16295953/… 【参考方案1】:您认为您的完成块被过早调用的问题是什么?
如果是这样,您是否检查过传递到完成块的布尔值的值?如果布尔值为真,您可能只想执行该块中的语句。
例如
[UIView animateWithDuration... animations:^
//do something
completion:^(BOOL finished)
if (finished)
// do something
];
我在动画开始之前调用完成块时看到了这个,但实际上是因为其他东西取消了动画,因此finished = NO
。
这并不能回答有关dispatch_after
的问题,因此您可能仍然遇到了那里的错误。
【讨论】:
我遇到了与上述问题相同的问题,即使 animateWithDuration 立即运行,finished 仍然是 YES【参考方案2】:问题标题和描述似乎不同(不清楚理解),无论如何如果你想在一段时间后产生任务然后看下面
dispatch_after 和 [UIView 动画:持续时间] 立即发生
这可以工作:
// Do your stuff OR animations then use below for DISPATCH_AFTER...
double delayInSeconds = 2.0f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
// Do your Stuff Or Add Animation
[UIView animateWithDuration:.6f animations:^
self.tableView.contentOffset = CGPointMake(0, 173);
];
);
【讨论】:
我认为提问者已经实现了动画的GCD调度。那不是问题。问题是,经过一定时间后,GCD 似乎忽略了队列中任务之间的间隔——只是立即或一次性启动其余计划任务。【参考方案3】:您的问题听起来好像您没有在 主线程 上调用动画和调度。这会导致意外行为,例如视图直到某个时间点才更新或移动。
请尝试像这样在 dispatch_main 中移动动画块:
dispatch_async(dispatch_get_main_queue(), ^
<# Code #>
);
看看它是否能解决问题。
【讨论】:
我正在调用主线程上的所有预定操作。如果不是这种情况,我认为动画最初不会表现出来。以上是关于dispatch_after 和 [UIView animation: duration] 立即发生(但不应该)的主要内容,如果未能解决你的问题,请参考以下文章
iOS GCD使用dispatch_after、dispatch_time、dispatch_walltime
如何延迟 dispatch_after 排队的块的执行? [复制]
GCD dispatch_after 调用导致 SIGBUS 信号
如何在 Swift 3、Swift 4 及更高版本中 dispatch_sync、dispatch_async、dispatch_after 等?