问题在于构建动画。活动监视器在调试此问题时非常有用。 Springboard的CPU使用率一直在上升,直到达到100%。所以时间显然不是在我的应用程序中花费的,而是在Springboard中的渲染服务器上。
我创建了两个带有巨大重复次数的动画,让它们永远运行。然后我将每个动画添加到一个单独的图层。为了创建动画,我使用了一个懒惰检查,并使用给定的键向图层询问任何现有的动画。如果图层没有任何返回,我创建了动画。问题是该层总是没有返回任何东西,所以我一直创造这些永远重复的动画。
这是有问题的代码。
// This call always returned nil.
CABasicAnimation *innerRotationAnimation = (CABasicAnimation *)[self.spinnerViewInner.layer animationForKey:@"rotationAnimation"];
// So I kept on creating animations and piling them up.
if (innerRotationAnimation == nil)
{
CATransform3D innerRotationTransform = CATransform3DMakeRotation(0.25f * M_PI * -1, 0, 0, 1.0);
innerRotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
innerRotationAnimation.toValue = [NSValue valueWithCATransform3D:innerRotationTransform];
innerRotationAnimation.duration = 0.25f;
innerRotationAnimation.cumulative = YES;
innerRotationAnimation.repeatCount = HUGE_VALF;
[self.spinnerViewInner.layer addAnimation:innerRotationAnimation forKey:@"rotationAnimation"];
}
要解决这个问题,我开始删除现有的动画。我可以在两个点上做到这一点,无论是在animationDidStop:finished:
回调,或在我的setAnimating:
方法,并且都工作正常。以下是setAnimating:
方法的更改。
- (void)setAnimating:(BOOL)animating
{
if (animating == NO) {
// Remove all existing animations now.
[self.layer removeAllAnimations];
}
else {
CABasicAnimation *animation = // Create animation;
[self.layer addAnimation:animation forKey:@"rotationAnimation"];
}
}
这里的原BROKEN代码,如果任何人的兴趣。
- (void)setAnimating:(BOOL)animating
{
if (self.isAnimating == animating)
{
return;
}
_animating = animating;
if (self.isAnimating == YES)
{
CABasicAnimation *innerRotationAnimation = (CABasicAnimation *)[self.spinnerViewInner.layer animationForKey:@"rotationAnimation"];
CABasicAnimation *outerRotationAnimation = (CABasicAnimation *)[self.spinnerViewOuter.layer animationForKey:@"rotationAnimation"];
if (innerRotationAnimation == nil)
{
CATransform3D innerRotationTransform = CATransform3DMakeRotation(0.25f * M_PI * -1, 0, 0, 1.0);
innerRotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
innerRotationAnimation.toValue = [NSValue valueWithCATransform3D:innerRotationTransform];
innerRotationAnimation.duration = 0.25f;
innerRotationAnimation.cumulative = YES;
innerRotationAnimation.repeatCount = HUGE_VALF;
[self.spinnerViewInner.layer addAnimation:innerRotationAnimation forKey:@"rotationAnimation"];
}
if (outerRotationAnimation == nil)
{
CATransform3D outerRotationTransform = CATransform3DMakeRotation(0.25f * M_PI * -1, 0, 0, -1.0);
outerRotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
outerRotationAnimation.toValue = [NSValue valueWithCATransform3D:outerRotationTransform];
outerRotationAnimation.duration = 0.25f;
outerRotationAnimation.cumulative = YES;
outerRotationAnimation.repeatCount = HUGE_VALF;
[self.spinnerViewOuter.layer addAnimation:outerRotationAnimation forKey:@"rotationAnimation"];
}
}
}
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
self.spinnerViewInner.layer.opacity = (self.isAnimating ? 1.0 : 0.0);
self.spinnerViewOuter.layer.opacity = (self.isAnimating ? 1.0 : 0.0);
}
虽然有一点我仍然很好奇。由于给定键只能有一个活动动画,因此当我尝试使用相同的键添加新动画时,Core Animation是否应该删除我的现有动画?为什么animationForKey:
完全返回nil
。
我正在使用包括Time Profiler,Core Animation,Open GL ES在内的各种工具,但它们并未指出任何问题区域。设备利用率保持在10-20%左右,所以我不会对GPU施加压力。时间事件探查器不会显示任何明显的增加每次迭代的工作量,所以这也没有帮助。你知道我可以用什么其他工具来调试更多吗? – Anurag
分配,泄漏和活动监视器。 – CuriousRabbit
感谢您的提示。 Activity Monitor是一个很好的开始,让我朝着正确的方向前进。 – Anurag