問題在於構建動畫。活動監視器在調試此問題時非常有用。 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