可可内存管理
在我的应用程序工作流程的各个阶段,我需要显示一个视图。该视图非常占用内存,因此我希望当用户丢弃它时将其释放。因此,我编写了以下代码:
- (MyView *)myView {
if (myView != nil)
return myView;
myView = [[UIView alloc] initWithFrame:CGRectZero]; // allocate memory if necessary.
// further init here
return myView;
}
- (void)discardView {
[myView discard]; // the discard methods puts the view offscreen.
[myView release]; // free memory!
}
- (void)showView {
view = [self myView];
// more code that puts the view onscreen.
}
不幸的是,此方法仅在第一次有效。将视图显示在屏幕上的后续请求会导致“消息发送到已解除分配的实例”
错误。显然,释放的实例与 nil 不同。我考虑过在 [myView release]
之后添加一行,内容为 myView = nil
。但是,这可能会导致错误(该行之后对 myView
的任何调用都可能会产生错误)。
那么,我该如何解决这个问题呢?
At various points during my application's workflow, I need so show a view. That view is quite memory intensive, so I want it to be deallocated when it gets discarded by the user. So, I wrote the following code:
- (MyView *)myView {
if (myView != nil)
return myView;
myView = [[UIView alloc] initWithFrame:CGRectZero]; // allocate memory if necessary.
// further init here
return myView;
}
- (void)discardView {
[myView discard]; // the discard methods puts the view offscreen.
[myView release]; // free memory!
}
- (void)showView {
view = [self myView];
// more code that puts the view onscreen.
}
Unfortunately, this methods only works the first time. Subsequent requests to put the view onscreen result in "message sent to deallocated instance"
errors. Apparently, a deallocated instance isn't the same thing as nil. I thought about putting an additional line after [myView release]
that reads myView = nil
. However, that could result in errors (any calls to myView
after that line would probably yield errors).
So, how can I solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将
myView
设置为nil
是正确的做法。 不这样做会产生错误,因为它无法检测到地引用了已释放的对象。您的代码测试nil
以查看是否需要创建新视图,因此您应该适当地设置该变量。Setting
myView
tonil
is the correct thing to do here. Not doing so is what's yielding errors, because it undetectably refers to a deallocated object. Your code tests fornil
to see if it needs to create a new view, so you should set the variable appropriately.你会遇到问题,因为你不使用访问器。您需要为视图定义一个属性。然后,每当您引用视图时,请使用自点符号。如果你这样做,那么只需将 view 属性设置为 nil,如下所示:
... 将自动触发其释放。
但是,这是管理视图的糟糕方法,尤其是从笔尖加载视图时。视图很可能是控制器对象的必需属性。将其设置为 nil 会导致崩溃。
更好的方法是让视图控制器处理内存问题。在 iPhone 上,您可以将内存管理代码放在
viewDidDisappear:
或didReceiveMemoryWarning
中。在任何情况下,只要控制器处于活动状态,您就不会终止视图,而是释放视图的内存密集型部分,例如图像。这使得视图成为一个轻量级的外壳对象。然后在“viewWillAppear”中,您将内存密集型部分加载回来。但是,处理此问题的最佳方法是实际从导航堆栈中弹出视图控制器。此时视图控制器会自动进行清理。
You're going to have problems because your not using accessors. You need to define a property for the view. Then whenever you refer to view use the self-dot notation. If you do this then simply setting the view property to nil like this:
... will trigger its release automatically.
However, this is bad way to manage the view especially if you load it from nib. The view most likely is a required property of a controller object. Setting it to nil invites crashes.
The better way is to have the view controller handle memory issues. On the iPhone you can put memory management code in
viewDidDisappear:
ordidReceiveMemoryWarning
. In any case you don't kill the view as long as the controller is alive but instead release the memory intensive parts of the view e.g. images. This leaves the view as a lightweight shell object. Then in 'viewWillAppear` you load the memory intensive parts back in.However, the best way to handle this problem is to actually pop the view controller from a navigation stack. At that point the view controller cleans up after itself automatically.