Garrett Albright
Garrett Albright

Reputation: 2841

Strategies for "realistically" testing low memory conditions in iOS Simulator

I'm at a point in the development of my little app where I'm implementing didReceiveMemoryWarning and such, but I feel like I don't have a good grasp on the best way to test what I'm implementing.

First off, apparently in the simulator, didReceiveMemoryWarning isn't triggered for apps that aren't in the foreground until that app is brought back into the foreground, according to this question - actually, that matches my own experience, but I was prone to ignore it because it doesn't really make sense. (Why would I want to delay clearing up my memory until I'm coming back into the foreground and probably about to need that data again?) Does this match the behavior of actual hardware? If so, does it make sense to cleanup tasks in applicationWillEnterBackground in addition to didReceiveMemoryWarning?

Second, generally, what is a good strategy for triggering the "Simulate Memory Warning" menu item in the simulator in such a way as to trigger memory warnings in a manner that they're likely to happen on the actual hardware?

Upvotes: 3

Views: 3531

Answers (2)

herzbube
herzbube

Reputation: 13378

Q1: Does this match the behavior of actual hardware?

  • A: Yes, the simulator and the actual device behave the same in this regard (e.g. if your app is suspended and is not running a background task, it does not receive applicationDidReceiveMemoryWarning).

Q2: Does it make sense to cleanup tasks in applicationWillEnterBackground?

  • A1: Only insofar as that your app must prepare itself for a complete restart. If your app remains suspended and the user does a lot of things with other apps, your app may become fully unloaded - even though the app may still be visible in the task switcher, when the user activates it the next time, your app delegate will receive application:didFinishLaunchingWithOptions: (not applicationWillEnterForeground:).
  • A2: I wouldn't bother with cleaning up memory, but you should make sure that by the time applicationWillEnterBackground has finished, any user preferences and other stuff are saved so that the app knows where to take up again when it is activated the next time.

Q3: What is a good strategy for triggering the "Simulate Memory Warning" menu item?

  • A1: I doubt whether a general strategy can be formulated since every app is different.
  • A2: To use a specific case: In my app, I don't use the app delegate's applicationDidReceiveMemoryWarning to relieve memory pressure, instead I rely on the fact that when a memory warning is sent, iOS also invokes viewDidUnload on certain view controllers that are not in use. Therefore I generally use the memory warning simulation to test whether my view controllers' viewDidLoad and viewDidUnload are balanced correctly.
  • A3: Concrete example: My app uses tabs, so a favorite scenario of mine is to 1) display the tab with the view controller (VC) under test; 2) navigate to a different tab; 3) simulate the memory warning (iOS invokes viewDidUnload in the VC under test); 4) navigate back the original tab (iOS invokes viewDidLoad in the VC under test).
  • A4: If you want to use a similar approach, then you have to figure out for your app which views might be unloaded by iOS. In my (limited) experience these tend to be views that are unrelated, such as views on different tabs.

Upvotes: 3

Mike M
Mike M

Reputation: 4436

Here's my answer to your second question - it also kind of answers your first question:

I've used the "Simulate Memory Warning" feature to effectively reproduce issues where a child view controller consumes enough memory such that its parent must free up resources.

For example, consider a child view controller that displays the camera/photo library (i.e., UIImagePickerController)). This uses a significant amount of memory. If the picker controller consumes more memory than is available, the parent's view controller will be unloaded, and once the parent view controller is shown again (when the child is popped), the parent's viewDidLoad will be called again. This means that any variables set in viewDidLoad will be set again, potentially with memory leaks or bad pointers.

The "Simulate Memory Warning" helps to find these problems. You can go into the child view controller, select "Simulate Memory Warning", then pop the view controller and check for problems.

Note that the "didReceiveMemoryWarning" is more relevant (imho) to let you know it happened than actually trying to release memory at that point.

Upvotes: 1

Related Questions