我的应用程序中有一点不寻常的情况,即
我必须在每次出现视图时重新加载一些保留属性,
代码如下所示:
// .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];
}
我的应用程序会在我推入并弹出视图一两次后崩溃,
哪一个真的错了?
非常感谢!
答案 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];
所以你的原始代码已经正确了。