iPad Mini 上的 iOS 内存管理

Posted

技术标签:

【中文标题】iPad Mini 上的 iOS 内存管理【英文标题】:iOS Memory Management on iPad Mini 【发布时间】:2013-10-16 13:55:25 【问题描述】:

我是 Objective C 和 ios 的新手,我在使用 iPad mini 时遇到内存问题,

我使用基于 nag 的应用程序,当我想在我使用的堆栈上推送 UIVIewController 时:

MyUIViewController *aController = [MyUIViewController alloc] initWithNibName:@"MyUIViewController" bundle:nil];

当我使用新的 XCode 5 内存调试导航器并在堆栈上推送一个新控制器时,我看到内存在增长,然后当我使用时:

[self.navigationController popViewControllerAnimated:YES];

我假设使用 ARC,控制器被释放,但内存永远不会下降。当我关闭 PopController 时也是如此。

我不明白,有没有办法在内存中释放这个控制器,以便我的应用程序可以完美运行?

我知道我必须在收到内存警告时释放屏幕上没有的内容 但在那种情况下,我被卡住了,因为我需要的一切都在屏幕上......

【问题讨论】:

你在这个控制器里做什么? 嗯,它不是一个单一的控制器,加载图像,加载声音,网络请求。 . .但一切都在屏幕上。是的,我在非视网膜上使用带有 [named] 的视网膜图像,因为该应用程序太大,无法上传到 3G/4G 50 Mb 限制。如果我从顶部控制器中删除视图,我必须将它们添加到 viewWillAppear 上? 您是否真的因为内存使用而遇到问题(例如 iOS 终止您的应用程序),还是您只是看到数字上升而担心? 没有应用程序停止我在 Xcode 上收到警告:由于内存压力而终止 [UIImage imageNamed:@""]; 不会从内存中释放图像,这可能是您的问题。请改用imageWithData 【参考方案1】:

因此,在 Instruments 中,您有几个工具可以帮助诊断您的问题。您可以使用 Memory Leak 工具查看您的视图控制器是否真的在泄漏内存,您也可以使用 Memory Allocation 工具创建堆快照来查看是否存在废弃内存的问题。 Here is a good tutorial about using Instruments for debugging.

【讨论】:

【参考方案2】:

您还没有提供源代码,但遇到此问题时,我有几点建议:

首先,在要弹出的UIViewController 上实现-(void)dealloc 方法,并查看在执行实际弹出时它是否被调用(在其中放置断点)。如果不是,则此 UIViewController 正在被其他对象保留。

使用静态分析器检查它是否在您的代码中发现问题:

还要确保您没有遇到保留周期。

对于块:

块将所有对象保留在其范围内,除非您明确告诉它们不要这样做。如果您的对象也保留此块,您将进入保留周期。为了防止这种情况,您通常希望创建一个指向自身的弱指针。

- (void)someMethod

    _weak id weakSelf = self;
    self.block = ^
        [weakSelf doSomething];  // retain cycle free!
    ;

作曲:

如果您有一个对象保留另一个对象,而另一个对象又保留第一个对象,您也会遇到一个保留循环。例如:

@interface ObjectA : NSObject

@property (strong, nonatomic) ObjectB *objectB;

@end

@implementation

- (id)init

    self = [super init];
    if (self) 
        self.objectB = [[ObjectB alloc] initWithObjectA:self]; // self.objectB gets retained
    

    return self;


@end

@interface ObjectB : NSObject

@property (strong, nonatomic) ObjectA *objectA; // the strong directive will cause a retain cycle, this should be weak

- (id)initWithAnObjectA:(ObjectA *)objectA;

@end

@implementation ObjectB

- (id)initWithAnObjectA:(ObjectA *)objectA;

    self = [super init];
    if (self) 
        self.objectA = objectA; // self.objectA gets retained, leading to a retain cycle
    

    return self;


@end

【讨论】:

谢谢,我会试一试,我怎么能确定我没有遇到保留周期(我正在使用 ARC) 我什么时候知道使用强或弱? 当您需要对象随时可用时,您使用strong。当您假设它可用时使用弱或赋值(对对象使用弱,对结构或数据类型使用赋值)。在我的示例中,您可以假设 objectB 的 objectA 随时可用,因为没有它,objectB 不存在。希望这是有道理的。 :P 好的,但是当 UIViewController 被弹出时会有所不同吗?当视图消失时,我必须将我的强引用设置为 nil 吗?对不起,如果我是个笨蛋。 如果你使用弱,ARC 会自动为你处理。 (将引用设置为 nil)。当你的视图控制器被弹出时,它应该被释放,假设它的保留计数达到 0。如果它没有被释放是因为你将它保留在其他地方。【参考方案3】:

将视图控制器添加到导航层次时使用自动释放视图控制器

MyUIViewController *aController = [[MyUIViewController alloc] initWithNibName:@"MyUIViewController" bundle:nil] autorelease];
[self.navigationController pushViewController:aController animated:YES];

【讨论】:

他正在使用 ARC,所以不允许自动释放 是的,我正在使用 ARC 。 . .

以上是关于iPad Mini 上的 iOS 内存管理的主要内容,如果未能解决你的问题,请参考以下文章

读书笔记iOS-属性中的内存管理参数

iPad View Controller 内存管理

IOS内存管理机制

ipad:图像加载和内存管理问题以及应用程序崩溃

ios查看app运行所占内存

iOS 7 onchange 事件在 iPad 3+Mini 中被破坏 // 需要解决