PDA

View Full Version : didReceiveMemoryWarning called with current controller view




Labeno
Nov 30, 2008, 01:37 PM
I'm trying to handling memory management properly using the didReceiveMemoryWarning signal in all controllers. I'm using loadView to allocate the visible resource (typically just a table view). When the didReceiveMemoryWarning function is called I do the following:

- (void)didReceiveMemoryWarning {
[self freeResources]; // Frees all resources allocated in loadView().
[super didReceiveMemoryWarning];
}

The problem I'm having is this is called even on the currently visible UITableViewController. This essentially frees the table view, but does not call loadView (probably cause the view is already visible). At this point tapping on a table cell does not do anything, and causes other issues.

The documentation implies that the didReceiveMemoryWarning is not called if the view controller is currently visible, but this is not the case.

This really causes havoc for me. Any ideas what the issue is?



PhoneyDeveloper
Dec 1, 2008, 10:30 AM
didRecieveMemoryWarning is called for all view controllers. The default behavior for the base UIViewController class is that, if it isn't visible then it releases its view hierarchy and sets its view property to nil. When the view controller later becomes visible it reloads its view hierarchy. UIViewController apparently determines if it's visible by seeing if its view property has a superview.

There are numerous traps in this process for the unwary.

Your subclass shouldn't delete the view hierarchy, let the base class do that. Design your subclass so that some or all of its resources can be loaded lazily. Design your viewDidLoad or loadView method so it can be called multiple times without memory leaks or other incorrect behavior. Your subclass shouldn't access the view property in didReceiveMemoryWarning. Accessing the view property will cause the view to load.

Although this doesn't affect you IBOutlets should be set up so they can be released in case of a memory warning. IBOutlets are retained when they are set, by default, so they won't be released by the base class.

Labeno
Dec 16, 2008, 08:20 AM
Question 1:
My app still exits due to the iPhone software forcing it to exit saying it was out of memory. I don't explicitly use IBOutlets, so how can I found out if a view hierarchy is actually being released. Should I just release all the views as they are created?

Question 2:
I allocate other view controllers in the loadView() function. Should I release those when the didReceiveMemoryWarning() is called, or are they automatically released? If I do have to release them, I just don't know how to do that, cause I don't know how to ask the view controller if it is currently visible view.

PhoneyDeveloper
Dec 16, 2008, 01:56 PM
Question 1:
My app still exits due to the iPhone software forcing it to exit saying it was out of memory. I don't explicitly use IBOutlets, so how can I found out if a view hierarchy is actually being released. Should I just release all the views as they are created?

This is an odd question. Yes, views should be released after they're added to the view hierarchy. Where are you releasing them now? dealloc?

Question 2:
I allocate other view controllers in the loadView() function. Should I release those when the didReceiveMemoryWarning() is called, or are they automatically released? If I do have to release them, I just don't know how to do that, cause I don't know how to ask the view controller if it is currently visible view.

I don't think you should release view controllers, just any resources that they hold that can be rebuilt. Each view controller will have didReceiveMemoryWarning called so you don't have to message them yourself.

Labeno
Dec 16, 2008, 02:20 PM
This is an odd question. Yes, views should be released after they're added to the view hierarchy. Where are you releasing them now? dealloc?


Sorry for the ambiguity.
I mean release them in the loadView() call, right where they are created. I see this a lot when looking at example code from Apple. Seems like they are implicitly retained, so they might need to be released as soon as they are created in order for them to properly be released later. It's all very confusing to me since I come from a C, C++ background where memory management seems so much easier.

PhoneyDeveloper
Dec 16, 2008, 05:30 PM
Yes, you should release them after you've added them to the view hierarchy. They are retained by their superview, so you would normally alloc/init, configure, addSubview, release.

Any time you alloc/init you must have a matching release somewhere.