IOS上内存管理的困惑
我的应用程序中有一个不太常见的情况,即
每次视图要出现时我都必须重新加载一些保留属性,
代码如下所示:
// .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”?
如果视图在释放之前出现多次(例如在 UINavigationController 中推入另一个视图并弹出多次),
那么 myData 将多次保留某个对象,但我只在释放中释放它 1一旦进入2号线,可以吗?
但是如果我将此方法添加到 viewController 中,我认为这对于避免内存泄漏更安全:
- (void)viewWillDisappear:(BOOL)animated {
self.myData = nil;
[myData release];
[super viewWillDisappear:animated];
}
- (void)dealloc {
// [myData release]; // don't release it here.
[super dealloc];
}
我的应用程序会在我推入和弹出视图一两次后崩溃,
那么哪一个是真正错误的呢?
多谢!
There's a little bit uncommon situation in my app, that is,
I have to reload some retain properties everytime when the view is going to appear,
the code looks like this:
// .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];
}
there are several points:
1st. as you see, the property "myData" is retain, so I think every I set some object for it, it would automatically retain that object?
2nd. I have to reload "myData" everytime the view will appear, just like the code of Line 1 above.
3rd. Since it is a retain property, I have to release it myself correctly.
Now, question is, do I correctly managed the memory without any leaking of "myData" using the codes above?
If the view would appear many times before it is dealloc, (like push in a further view in a UINavigationController and pop out for several times),
then myData would retain some object more than once, but I only release it in the dealloc for 1 once in Line 2, so is that ok?
But if I add this method the to viewController,which I think is more safe for avoiding memory leaks:
- (void)viewWillDisappear:(BOOL)animated {
self.myData = nil;
[myData release];
[super viewWillDisappear:animated];
}
- (void)dealloc {
// [myData release]; // don't release it here.
[super dealloc];
}
my app would crash after one or two times I push in and pop out the view,
So which one is really wrong?
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不仅要在第 2 行中释放它,而且在替换时也会在第 1 行中以及
viewDidUnload
中释放它,因此您上面的代码就没有问题。关键是来扩展为
通过分配您已经隐式调用
release
的任何内容(包括nil
) so 。事实上,您可以将第 2 行替换为 self.myData = nil;,这样就永远不会调用release
,因为您没有任何显式的retain
。You are not only releasing it in Line 2, it will be also released in Line 1 when replaced as well as in
viewDidUnload
, so your code on top is just fine. The key is thatis expanded to
so by assigning anything (including
nil
) you are already callingrelease
implicitly. You could in fact replace Line 2 withself.myData = nil;
to have never to callrelease
since you don't have any explicitretain
..h
.m
通过在代码中包含这些行,将为您的属性 myData 创建 setter 和 getter。在运行时为对象生成的 setter 看起来像这样,
总的效果是,每当您通过在前面附加 self 来访问属性时,实际上都是在调用 setter 和 getter。所以下面两行是完全相同的。
所以你原来的代码已经是正确的。
.h
.m
By including these lines in your code a setter and getter is created for your property myData. The setter generated at run time for objects looks something like this,
The total effect is that whenever you access the property by appending self in front you are actually calling the setters and getters. So the following two lines are the exact same.
So your original code was already correct.