gpt4 book ai didi

objective-c - 长时间使用后应用程序和操作系统滞后

转载 作者:行者123 更新时间:2023-11-28 20:27:31 25 4
gpt4 key购买 nike

我有一个应用在使用大约 30-35 分钟后会降低整个操作系统的速度。滞后是渐进的,我可以看到它随着时间的推移而累积,因为我一遍又一遍地重复相同的操作。这是一个音乐应用程序,在播放大约 15-20 首轨道后,延迟是无法忍受的。

在 UIScrollView 中滚动项目时,帧率下降到 10 以下。许多帧被跳过,UI 几乎被锁定。如果我为该应用程序设置后台,我会在 SpringBoard 的操作系统中看到这种滞后,而且基本上无处不在。在 SpringBoard 中滚动应用程序图标变得不稳定。滑动解锁变得断断续续等

我将如何着手解决这个问题?可能是什么原因。由于代码库相当复杂,我无法削减代码来创建最小的可重现示例。我需要帮助来了解可能导致操作系统几乎锁定的原因。这不是死锁,因为 UI 仍然有响应,只是需要很长时间。

哪些分析工具可以帮助阐明此问题的原因?我怀疑这可能是因为内存泄漏,但令人惊讶的是,操作系统并未向应用程序发送内存警告,所以我对此也不太确定。

非常感谢任何帮助。

最佳答案

问题出在动画的构建上。事件监视器在调试此问题时最有用。 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

关于objective-c - 长时间使用后应用程序和操作系统滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13501152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com