困惑IOS上的内存管理

时间:2012-02-12 03:33:41

标签: ios memory-management properties retain

我的应用程序中有一点不寻常的情况,即

我必须在每次出现视图时重新加载一些保留属性,

代码如下所示:

// .h
@property (nonatomic, retain) NSArray *myData;
// .m
@synthesize myData;
- (void)viewWillAppear:(BOOL)animated {
    ... // get FetchRequest and so on
    self.myData = [self.context executeFetchRequest:request error:&error]; // Line 1
[super viewWillAppear:animated];
}
- (void)viewDidUnload {
    self.myData = nil;
    [super viewDidUnload];
}
- (void)dealloc {
    [myData release];  // Line 2
    [super dealloc];
}

有几点:

第一。正如你所看到的,属性“myData”是保留的,所以我认为我为它设置了一些对象,它会自动保留该对象吗?

第二。每次出现视图时我都要重新加载“myData”,就像上面第1行的代码一样。

第三。由于它是一个保留属性,我必须自己正确释放它。

现在,问题是,我是否使用上述代码正确管理内存而没有泄漏“myData”?

如果视图在dealloc之前出现多次,(比如在UINavigationController中进一步查看并弹出多次),

然后myData会不止一次保留一些对象,但是我只在第2行的dealloc中释放它一次,所以可以吗?

但是,如果我将此方法添加到viewController,我认为这对于避免内存泄漏更安全:

- (void)viewWillDisappear:(BOOL)animated {
    self.myData = nil;
    [myData release];
[super viewWillDisappear:animated];
}
- (void)dealloc {
 //   [myData release];  // don't release it here.
    [super dealloc];
}

我的应用程序会在我推入并弹出视图一两次后崩溃,

哪一个真的错了?

非常感谢!

2 个答案:

答案 0 :(得分:1)

您不仅会在第2行发布它,它还会在替换时以及viewDidUnload中的第1行中发布,因此您的代码就可以了。关键是

self.myData = anything;

扩展为

[self->myData release];
self->myData = [anything retain];

所以通过分配任何内容(包括nil),您已经隐式调用了release。实际上,您可以使用self.myData = nil;替换第2行,因为您没有任何明确的release,所以永远不会致电retain

答案 1 :(得分:0)

.h

@property (nonatomic, retain) NSArray *myData;

的.m

@synthesize myData;

通过在代码中包含这些行,可以为属性myData创建一个setter和getter。在运行时为对象生成的setter看起来像这样,

- (void)setMyData: (id)newValue
{
    if (myData != newValue)
    {
        [myData release];
        myData = newValue;
        [myData retain];
    }
}

总效果是,无论何时通过在前面附加self来访问该属性,您实际上都在调用setter和getter。所以以下两行完全相同。

self.myData = nil;
[self setMyData:nil];

所以你的原始代码已经正确了。