views:

4227

answers:

1

Background: I have a tab bar application. Each tab contains navigation controller allowing the user to transition from one view to the other showing a drill down information of the data (each view is being handled by a view controller and each view controller class has -didReceiveMemoryWarning method). Lists are populated by pulling the data from web services.

Problem: When i use "Hardware > Simulate Memory Warning" option of iPhone Simulator, the -didReceiveMemoryWarning method is called for ALL my view controllers - even the one which the user is viewing. I don't want to clear any content which is being used by the active view controller. How can i achieve that?

Which method should have the implementation to reload the data after the data was released because of memory warning? (I see that the view controller classes that contain a table view call -viewDidLoad method when user comes back to that view, but if the view contains (say UIWebView) then -viewDidLoad method is not called. Why is that?)

Editted (Friday 30 January 2009 - 03:10 PM)

Note: I'm using Interface builder for creating views. and loadView method is commented out.

So, when a view controller receives a memory warning message, these are the steps that are carried out:

  1. Following method is called:
- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning]; 
}
  1. As a result of call to [super didReceiveMemoryWarning], [self setView:nil] gets automatically called?

  2. If any resources should be cleared, then -setView method should be overwritten to clear local resources.

  3. [self setView:nil] is not called if the view is currently active (By default). Right? - I'm really curious which method takes this decision and how?

Can you please confirm. Plus i was getting an error following this approach but adding myObject = nil after releasing myObject in dealloc method of controller class fixed the issue. Thanks.

+6  A: 

I do my clean up like this:

-(void)setView:(UIView*)view
{
    [super setView:view];
    if(view == nil)
    {
       // Our view has been cleared, therefore we should clean up everything 
       // we are not currently using
....

setView:nil is called by UIViewController in response to a memory warning, if that view is not currently visible - which is basically what you want to know.

EDITED

In answer to the followups:

  1. Correct.
  2. That's what I do, and it works for me.
  3. Correct. The implementation of didReceiveMemoryWarning in UIViewController is what does this. If you don't override didReceiveMemoryWarning, then the base class implementation in UIViewController will be called - if you do override it, obviously you should call

    [super didReceiveMemoryWarning]

Airsource Ltd
Even if i don't override didReceiveMemoryWarning method, my view is cleared. Why is that?
Mustafa
Not overriding means you get the default behaviour implemented by UIViewController, which is to clear your view. If your override simply calls the super implementation, that's the same as having no override at all.
Airsource Ltd