gpt4 book ai didi

ios - 了解 iOS 上的 Instruments 内存分配日志

转载 作者:技术小花猫 更新时间:2023-10-29 11:23:08 26 4
gpt4 key购买 nike

我已经构建了一个即将完成的 iOS 应用程序,但是,我最近遇到它由于“内存压力”而崩溃的情况。因此,我开始分析 Instruments 中的内存分配情况,可以肯定的是,该应用程序确实使用了大量内存,而且似乎只在使用期间增加。

但是,对于 Instruments 内存分配来说相对较新,我不太能够破译 52% 的分配是在哪里进行的,如下面的屏幕截图所示:

enter image description here

这显然与Core Animation有关,但具体是什么我很难确定,所以我认为一些聪明的头脑可能知道答案。

面包屑:

我的应用程序使用自定义转场,在 View Controller 之间移动时会出现大量动画。这是一个例子:

@interface AreaToKeyFiguresSegue : UIStoryboardSegue

@end

...

@implementation AreaToKeyFiguresSegue

- (void)perform
{
[self sourceControllerOut];
}

- (void)sourceControllerOut
{
AreaChooserViewController *sourceViewController = (AreaChooserViewController *) [self sourceViewController];
KeyFigureViewController *destinationController = (KeyFigureViewController *) [self destinationViewController];

double ratio = 22.0/sourceViewController.titleLabel.font.pointSize;

sourceViewController.titleLabel.adjustsFontSizeToFitWidth = YES;

[UIView animateWithDuration:TRANSITION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{

// Animate areaChooser
sourceViewController.areaChooserScrollView.alpha = 0;
sourceViewController.areaScrollViewVerticalSpaceConstraint.constant = -300;

sourceViewController.backButtonVerticalConstraint.constant = 20;
sourceViewController.backButton.transform = CGAffineTransformScale(sourceViewController.backButton.transform, ratio, ratio);
sourceViewController.backButton.titleLabel.textColor = [UIColor redKombitColor];

sourceViewController.backArrowPlaceholderVerticalConstraint.constant = 14;
sourceViewController.backArrowPlaceholder.alpha = 1;

sourceViewController.areaLabelVerticalConstraint.constant = 50;
sourceViewController.areaLabel.alpha = 1;

[sourceViewController.view layoutIfNeeded];

} completion:^(BOOL finished) {
[destinationController view]; // Make sure destionation view is initialized before animating it
[sourceViewController.navigationController pushViewController:destinationController animated:NO]; // Push new viewController without animating it

[self destinationControllerIn]; // Now animate destination controller
}];
}

- (void)destinationControllerIn
{
AreaChooserViewController *sourceViewController = (AreaChooserViewController *) [self sourceViewController];
KeyFigureViewController *destinationController = (KeyFigureViewController *) [self destinationViewController];

destinationController.keyFigureTableViewVerticalConstraint.constant = 600;
destinationController.keyFigureTableView.alpha = 0.0;
destinationController.allFavoritesSegmentedControl.alpha = 0.0;
[destinationController.view layoutIfNeeded];
[sourceViewController.segueProgress setHidden:YES];
}

@end

每当要弹出一个 View Controller 时,我只是做相反的事情:

- (IBAction)goBack:(id)sender
{
[UIView animateWithDuration:TRANSITION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{

[self.keyFigureTableView setAlpha:0];
self.keyFigureTableViewVerticalConstraint.constant = 700;
[self.allFavoritesSegmentedControl setAlpha:0];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[self.navigationController popViewControllerAnimated:NO]; // Pop viewController without animating it
}];
}

编辑:

大部分内存分配发生在推送 View Controller 时,即使它之前已经显示过。 IE。从

A -> B -> C

B <- C

B -> C

其中“->”= push,“<-”= pop,每个“->”分配更多内存,“<-”从不释放任何内存。

更多详情

根据 Instruments,我没有僵尸并且没有泄漏。静态分析也没有给出任何结果。我的应用一直在分配内存,直到它最终崩溃。

我大约 70% 的内存分配发生在以下调用堆栈中,这与我的代码无关(倒置调用树):

enter image description here

最佳答案

下面是我调试它们的方法。

  1. 在 Instruments 中,使用 Allocations 工具并打开“Record reference counts”

enter image description here

  1. 将您的应用运行到“稳定状态”,包括多次执行您认为泄漏的操作。

  2. 在 Instruments 中,使用输入/输出标记设置您的基线内存水平。

  3. 执行几次您认为泄漏的操作。 (比如 7)

  4. 在 Instruments 中,切换到显示所有分配的 View 并查找已分配但未释放次数与您刚刚执行的操作相同的对象(同样可能是 7 次)。您首先要尝试找到一个特定于您的程序的对象...因此更喜欢 MyNetworkOperation 实例,而不是像 NSData 这样的通用基础类。 click arrow next to class you are interested in click arrow next to an allocated object

  5. 选择一个尚未解除分配的对象并查看其分配历史记录。您将能够看到所讨论对象的每个 alloc/retain/release/autorelease 的调用堆栈。可能其中一个调用对您来说看起来很可疑。 history of retain/release for selected object

我想这些步骤更适用于非 ARC 环境。在 ARC 下,您可能正在寻找保留周期的东西。

一般来说,你可以通过确保你的强引用只在一个方向上来避免循环保留...例如,一个 View 对其 subview 有强引用,并且每个 subview 只能使用弱引用来引用任何父 View .或者你的 View Controller 可能对你的 View 有很强的引用。您的 View 必须仅对其 View Controller 有弱引用。另一种说法是在每个关系中决定哪个对象“拥有”另一个对象。

关于ios - 了解 iOS 上的 Instruments 内存分配日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20471973/

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