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 内存管理的主要内容,如果未能解决你的问题,请参考以下文章