Ios: Helpfulness of Didreceivememorywarning:

iOS: helpfulness of didReceiveMemoryWarning:

OK, several things to note:

  • didReceiveMemoryWarning will be called before an out-of-memory crash. Not other crashes. If you handle the warning properly and free up memory, then you can avoid the out-of-memory condition and not crash.
  • You can manually trigger a memory warning in the simulator under the Hardware menu. Highly recommend doing this to test your handling of didReceiveMemoryWarning.
  • Instruments helps you debug leaks (though not all of them) - it's not really that useful for crashes.
  • No, I don't personally use NSLog - I just breakpoint the memory warnings when I'm debugging.

How to implement didReceiveMemoryWarning?

One example i am posting...which i have copied from somwhere... it might give you some idea...

- (void)didReceiveMemoryWarning {

// Release anything that's not essential, such as cached data (meaning
// instance variables, and what else...?)

// Obviously can't access local variables such as defined in method
// loadView, so can't release them here We can set some instance variables
// as nil, rather than call the release method on them, if we have defined
// setters that retain nil and release their old values (such as through use
// of @synthesize). This can be a better approach than using the release
// method, because this prevents a variable from pointing to random remnant
// data. Note in contrast, that setting a variable directly (using "=" and
// not using the setter), would result in a memory leak.
self.myStringB = nil;
self.myStringD = nil;
[myStringA release];// No setter defined - must release it this way
[myStringC release];// No setter defined - must release it this way

/* 3. MUST CONFIRM: NOT necessary to release outlets here - See override of
setView instead.
self.labelA = nil;
self.imageViewA = nil;
self.subViewA = nil;
*/
// Releases the view if it doesn't have a superview
[super didReceiveMemoryWarning];
}

How to implement didReceiveMemoryWarning in Swift?

Swift

Swift uses ARC just like Objective-C does (source to Apple Docs). The same kind of rules apply for freeing memory, remove all of the references to an object and it will be deallocated.

How to free memory

I assume that disposing of resources means setting them to nil, but what exactly are "resources that can be recreated"?

"resources that can be recreated" really depends on your application.

Examples

Say you are a social media app that deals with a lot of pictures. You want a snappy user interface so you cache the next 20 pictures in memory to make scrolling fast. Those images are always saved on the local file system.

  • Images can take up a lot of memory
  • You don't need those images in memory. If the app is low on memory, taking an extra second to load the image from a file is fine.
  • You could entirely dump the image cache when you receive that memory warning.
  • This will free up memory that the system needs

You are creating an amazing game that has a number of different levels.
Loading a level into your fancy game engine takes a while so if the user has enough memory you can load level 3 while they are playing level 2.

  • Levels take up a lot of memory
  • You don't NEED the next level in memory. They are nice to have but not essential.
  • LevelCache.sharedCache().nextLevel = nil frees up all that memory

What shouldn't you deallocate

Never deallocate the stuff that is on screen. I've seen some answers to related questions deallocate the view of the UIViewController. If you remove everything from the screen you might at well crash (in my opinion).

Examples

If the user has a document open that they are editing, DON'T deallocate it. Users will get exceptional angry at you if your app deletes their work without ever being saved. (In fact, you should probably have some emergency save mechanism for when that happens)

If your user is writing a post for your fabulous social media app, don't let their work go to waste. Save it and try to restore it when they open the app again. Although it's a lot of work to setup I love apps that do this.

Note

Most modern devices rarely run out of memory. The system does a pretty good job of killing apps in the background to free up memory for the app running in the foreground.
You have probably seen an app "open" in the App Switcher yet when you tapped on the app it opened to its initial state. The OS killed the app in the background to free up memory. See State Restoration for info on how to avoid this problem.

If your app is getting consistent memory warnings when you aren't doing a huge amount of processing make sure that you aren't leaking memory first.
Detecting memory leaks is outside the scope of this answer. Docs and a tutorial.

When is didReceiveMemoryWarning actually called

It's called when the system has low memory, then you need to purge your UIViewController.

You can simulate a memory warning in the Simulator: Hardware > Simulate Memory Warning and see what happens.

If you are supporting prior versions to iOS6 it's important to take note of the following from Apple's documentation:

Prior to iOS 6, when a low-memory warning occurred, the
UIViewController class purged its views if it knew it could reload or
recreate them again later. If this happens, it also calls the
viewWillUnload and viewDidUnload methods to give your code a chance to
relinquish ownership of any objects that are associated with your view
hierarchy, including objects loaded from the nib file, objects created
in your viewDidLoad method, and objects created lazily at runtime and
added to the view hierarchy. On iOS 6, views are never purged and
these methods are never called. If your view controller needs to
perform specific tasks when memory is low, it should override the
didReceiveMemoryWarning method.

About the threshold, I try not to exceed 12MB of memory.

Memory Warning in Xcode - What does one do in didReceiveMemoryWarning?

Of course you still have control over memory. You're just operating at a higher abstraction level with ARC.

You can use: object = nil to clear a strong reference. When all strong references are cleared, the object is deallocated.

If you are familiar with manual reference counting:

object = nil; << ARC

is like this when doing your own reference counting:

[object release], object = nil;

What does ios when it calls didreceivememorywarning?

There is a nice discussion about DidReceiveMemoryWarning in this question: iOS: helpfulness of didReceiveMemoryWarning:

iOS 4.0.1 fast app switching behavior in simulator vs device (iPhone 4)

Maybe your phone is low on memory.

My app closes without any warning or error message

Sounds like you're running out of memory.

A few quick tips that might help out:

  • Check your memory profile over time using Instruments. If you see a steady incline over time, it's likely to be a memory leak, or an inefficient algorithm that is allocating more memory than you need.
  • Use a static analyzer to help check for leaks, such as Clang.
  • Images and image-related files are particularly memory-hungry, so focus on efficiency for them. When you work with textures in OpenGL, use the PVRTC format, which offers awesome compression.
  • didReceiveMemoryWarning: is your friend - aka a good chance to throw out anything you don't absolutely need in memory. Better to be memory-efficient the whole time, though.


Related Topics



Leave a reply



Submit