Ios 视图控制器/内存管理
我对视图控制器中的内存管理有点困惑 假设我有这样的头文件:Ios 视图控制器/内存管理,ios,objective-c,memory-management,viewcontroller,Ios,Objective C,Memory Management,Viewcontroller,我对视图控制器中的内存管理有点困惑 假设我有这样的头文件: @interface MyController : UIViewController { NSMutableArray *data; } @property (nonatomic, retain) NSMutableArray *data; @end 而.m文件看起来是这样的: @implementation MyController @synthesize data; - (void)dealloc { [sel
@interface MyController : UIViewController {
NSMutableArray *data;
}
@property (nonatomic, retain) NSMutableArray *data;
@end
而.m文件看起来是这样的:
@implementation MyController
@synthesize data;
- (void)dealloc
{
[self.data release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.data == nil)
self.data = [[NSMutableArray alloc] init];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[self.data release];
self.data = nil;
}
从正确的内存管理角度来看,这样可以吗?通过内存警告解除锁定后,该功能是否有效?你是如何在你的应用程序中做到这一点的
谢谢你的回答;) 虽然
alloc retain
在viewdiload
和viewdiload
中调用balance out,并且在内存方面应该没有问题,但是只获取一次所有权并放弃一次而不是两次会更干净
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.data == nil)
self.data = [NSMutableArray array];
}
及
不能保证
viewDidUnload
会被调用。与成对调用的init/dealloc不同,viewDidUnload
是不确定调用的<仅当内存不足且您的视图不是活动视图时,才会调用code>viewDidUnload
根据您的模型是如何创建的,以及它在内存中的含义,您不删除它可能更有意义。这方面的一个例子可能是,重新创建该数据可能涉及昂贵的web服务调用。因此,必须等待数据重新创建,这将是一种糟糕的用户体验。如果它一定要去,一个更好的策略可能是将数据缓存到磁盘,以便您可以轻松地重建它
viewDidUnload
应该只包含清理您的IBOutlet
s和轻松刷新可重新创建的数据。来自-viewDidUnload
的这些行同时释放数据
:
[self.data release];
self.data = nil;
由于您在第二行中使用了属性setter,并且data
是一个保留的属性,因此setter将释放data
。这是过度释放,它会立即或稍后导致崩溃,具体取决于其他对象是否也保留该对象。要解决这个问题,只需删除第一行并依靠setter来做正确的事情
另一方面,-dealoc
方法不应该像现在这样使用setter。您应该更改:
[self.data release];
致:
这里的理由是,可以想象这个类可以被子类化,有人可能会以这样的方式重写属性setter,即它有一些副作用,在对象被释放时可能会导致问题。您应该直接访问ivar——请注意,我没有使用“self”,因此我们处理的是ivar,而不是属性访问器。(
-init
和-dealloc
是您唯一需要担心的地方;在其他地方使用属性访问器。)我不同意。在出现内存不足警告时,将此代码放入viewDidLoad
和viewDidUnload
有助于节省空间。如果从未调用过viewDidLoad
,则他不需要为从未查看过的对象分配内存。但是,如果他在viewController加载之前或卸载之后访问它的实例,那么他最好在init
中使用data
,并在dealloc
@PengOne中释放它-他可以在viewDidLoad
中进行数据加载,以避免不必要地加载数据。然而,我建议OP先分析他的需求,然后再明确地将其插入viewDidUnload
。如果数据很容易重新创建,请务必将其放入viewDidUnload
中。否则,一有麻烦就把它扔掉是不好的做法。还有其他一些策略可以缓解内存问题,同时仍然能够以快速、用户友好的方式返回数据。嗯,在内存警告后,我在模拟器中出现内存泄漏,使用-viewDidUnload而不使用[self.data release]……这不就是我保留数据两次吗?第一次是通过init,第二次是通过“保留”属性?@Michal,是的,你说得对。我同意@Deepak——最好只保留一个。使用他的示例中的[NSMutableArray]
,或者只需向您的版本添加自动释放。
[self.data release];
[data release];
data = nil; // this line isn't strictly necessary, but often considered good form