IPhone Development - Simulate Memory

Background

I have a tab bar app. Each tab contains a navigation controller that allows the user to switch from one view to another, showing data granularity information (each view is processed by the view controller, and each view controller class has a didReceiveMemoryWarning method). Lists are populated by pulling data from web services.

Problem

When I use the "Hardware> Simulate Memory Warning" option for iPhone Simulator, the didReceiveMemoryWarning method didReceiveMemoryWarning called for ALL of my view controllers β€” even the one that the user is viewing. I do not want to clear the content that is used by the active view controller. How can i achieve this?

What method should an implementation have to reload data after the data has been released due to a memory warning? (I see that the view controller classes containing the method to call the viewDidLoad table when the user returns to this view, but if the view contains (for example, UIWebView), then the viewDidLoad method viewDidLoad not called. Why is this?)

Edited (Friday January 30, 2009 - 3:10 p.m.)

(Note: I am using an interface constructor to create views, and the loadView method loadView commented out.)

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

  • The following method is called:

     - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } 
  • As a result of calling [super didReceiveMemoryWarning] , [self setView:nil] automatically called?

  • If any resources need to be cleared, then the setView method must be rewritten to clear local resources.

  • [self setView:nil] not called if the view is currently active (default). Right? β€œI'm really interested in which method makes this decision and how?”

Could you confirm. Also, I was getting an error following this approach, but adding myObject = nil after releasing myObject to dealloc the controller class method fixed the problem. Thank.

+5
memory iphone warnings simulator
Jan 29 '09 at 10:00
source share
5 answers

This is an old question, but I do not see the correct answer, so here:

When a memory -didReceiveMemoryWarning is -didReceiveMemoryWarning is called on all view controllers, regardless of whether they are "current" or not. View controllers simply listen for memory event alerts.

If the view controller view is not used during a memory warning, the controller will unload it by setting the property to nil. How do I know if this view is being used? According to the view -superview property. If view.superview is zero, the view is not part of any tree and can be safely unloaded.

As soon as this happens, the -viewDidUnload controller is -viewDidUnload . This is the right place to unload any outlets and everything that will be recreated in -viewDidLoad .




So what is -didReceiveMemoryWarning for? Your controller may have objects that will not be displayed until accessed. For example, you might have a controller that sometimes needs a large chunk of data from a file, but not always. You may have a property set for it as follows:

 - (NSData*)bigChunkOfData { // Get data from our instance variable _data, read from disk if necessary if (_data == nil) { _data = [[NSData alloc] initWithContentsOfFile:@"/path/to/data"]; } return _data; } 

This reads data from the disk for the first time, and then saves it in the instance variable. Since the _data variable is created on demand, it’s safe for us to unload it in low memory situations: it will just be created again the next time we need it.

 - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; [_data release]; _data = nil; // <-- Very important: don't leave strong references dangling. } 
+12
May 05 '11 at 3:43
source share

I do it like:

 -(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 the UIViewController in response to a memory warning, if this view is not currently visible - this is basically what you want to know.

edited

In response to the following actions:

  • Right.
  • What am I doing and it works for me.
  • Right. The implementation of didReceiveMemoryWarning in the UIViewController is what this does. If you do not override didReceiveMemoryWarning , then the base class implementation in the UIViewController will be called - if you override it, obviously you should call:

     [super didReceiveMemoryWarning] 
+8
Jan 29 '09 at 10:31
source share

Regarding view management and memory alerts:

UIKit does not allow navigation only from the view controller, but also allows navigation to other view controllers from existing ones. In this case, the new UIViewController will be highlighted and then loaded into view. The old view controller will shut down and become inactive, but still owns many objects - some in user-defined properties and variables, and others in the view / view hierarchy. As well as the new visible view controller, in relation to its view objects.

Due to the limited memory capacity of mobile devices, owning two sets of objects β€” one in the external screen controller and the other in the screen controller β€” may be too large to process. If UIKit deems it necessary, it can return some part of the dispatcher's memory off-screen, which is not yet shown; UIKit knows which view controller is on the screen and which one is off the screen, because in the end it controls them (when you call presentModalViewController:animated: or dismissModalViewControllerAnimated: . This way, every time it feels pressure, UIKit generates a memory warning that unloads and releases the non-screen view from the view hierarchy, and then calls your own viewDidUnload method so that you do the same for your properties and variables. UIKit automatically runs self.view, allowing us to manually release our variables and properties in our viewDidUnload code. It does this for all controllers without a screen.

When the system runs out of memory, it starts didReceiveMemoryWarning . Off-screen will be restored and released after a warning about the memory, but your screen view will not be released - it is visible and necessary. If your class has a lot of memory, such as caches, images, etc., didReceiveMemoryWarning is where you need to clear them, even if they are on the screen; otherwise, your application may be interrupted to use system resources. You need to override this method to clear memory; just remember that you are calling [super didReceiveMemoryWarning]; .

A more detailed explanation is available here: http://myok12.wordpress.com/2010/11/30/custom-uiviewcontrollers-their-views-and-their-memory-management/

+1
Dec 01 2018-10-12T00:
source share

To ensure that I do not need to handle this for each individual view manager, I write .. I just created an Xcode ViewController template that contains recommendations on which objects should be released and when ..

more explanation here http://iphone2020.wordpress.com/2010/05/30/efficient-memory-handling-in-uiviewcontroller-part-1/

I hope you find it useful.

+1
Jan 29 2018-11-11T00:
source share

Fortunately, the simulator has a convenient feature that allows you to test low memory tests. Put some NSLog () statements in viewDidLoad and didReceiveMemoryWarning, for example: οΏΌ

 - (void)viewDidLoad { NSLog(@"viewDidLoad"); ... } - (void)didReceiveMemoryWarning { NSLog(@"didReceiveMemoryWarning"); } 
0
May 29 '14 at 16:05
source share



All Articles