Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 视图控制器/内存管理_Ios_Objective C_Memory Management_Viewcontroller - Fatal编程技术网

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