2012-11-21 31 views
0

我有一個應用程序在使用約30-35分鐘後會減慢整個操作系統。滯後是漸進的,我可以看到它隨着時間的推移而增加,因爲我一遍又一遍地重複同樣的操作。這是一款音樂應用程序,在流過大約15-20首曲目後,延遲是無法忍受的。長時間使用後應用程序和操作系統滯後

在UIScrollView中滾動項目時,幀頻會降到10以下。很多幀被跳過,用戶界面幾乎鎖定。如果我爲應用程序提供背景,那麼SpringBoard中的操作系統以及基本上任何地方都會出現這種滯後現象。在SpringBoard中滾動應用程序圖標變得不連貫。解鎖幻燈片變得波濤洶涌,等等。

我該如何解決這個問題?可能是什麼原因。由於代碼庫相當複雜,我無法削減代碼以創建最小可重現的示例。我需要幫助瞭解可能導致操作系統幾乎鎖定的原因。這不是一個僵局,因爲用戶界面仍然響應,但只是需要很長時間。

什麼分析工具可以幫助照亮這個問題的原因?我懷疑它可能是因爲內存泄漏,但令人驚訝的是操作系統沒有發送應用程序內存警告,所以我也不完全確定。

任何幫助,非常感謝。

回答

2

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

1
+0

我正在使用包括Time Profiler,Core Animation,Open GL ES在內的各種工具,但它們並未指出任何問題區域。設備利用率保持在10-20%左右,所以我不會對GPU施加壓力。時間事件探查器不會顯示任何明顯的增加每次迭代的工作量,所以這也沒有幫助。你知道我可以用什麼其他工具來調試更多嗎? – Anurag

+0

分配,泄漏和活動監視器。 – CuriousRabbit

+0

感謝您的提示。 Activity Monitor是一個很好的開始,讓我朝着正確的方向前進。 – Anurag

相關問題