Simulating memory warnings does not unload views


#1

Hi, I am using XCode45-DP4 and running the iOS 6 beta on my phone, so this may be a difference due to that. I have tried simulating memory warnings multiple times but I never see the log messages for either of the Hypnosis or Time view controllers that says they loaded their view. I see them each one time when I load their view the first time, but never again, even if I simulate memory warnings.

Anyone know why this is the case?

Actually – I also noticed that I see the “time view controller loaded its view” and the “hypnosis view controller loaded its view” messages right away when the app starts up, before I have even clicked on the “Time” tab bar item for the first time.


#2

I figured it out. In the documentation for iOS 6 for viewDidUnload it says this:

[quote]Called when the controller’s view is released from memory. (Deprecated in iOS 6.0. Views are no longer purged under low-memory conditions and so this method is never called.)
[/quote]

Does this mean specifying IBOutlets as __weak references is no longer necessary?


#3

I was asking myself the same question after I switched to the iOS6 SDK. As far as I understand though I would still use __weak IBOutlet pointers as long as the outlet itself is part of a view hierarchy.
I currently can’t think of a scenario where my view controller would need a pointer to an outlet when the corresponding view isn’t existing anymore, but maybe this is because I’m fairly new to cocoa touch / objective c. In fact I think a __weak outlet will make manually unloading a view safer as you don’t have to set the outlet pointer to nil (you can forget to do that and this will cause an unnecessary object lying around in the heap until the view is loaded again and the pointer is set to the new outlet).

Can someone with more experience maybe tell if this is considered correct or not? Are there even scenarios where you unload your view manually? Or is it just up to the developer’s requirements / preferences? Any input would be much appreciated.


#4

Yup, they changed this in iOS 6. Crazy stuff.

Low memory warnings no longer automatically destroy views that are off the screen. The reason is - and I’m still investigating the details so I can write about it in a blog post - the expensive part of a view was its image that represented it. Instead of destroying the entire view, just its image is “destroyed”. (I say “destroyed” with quotes because it is actually marked as unclaimed memory and can be reclaimed, which is such an intensely awesome optimization that I just grinned like an idiot when I saw it.)

There will be times where you have a view that takes up a lot of memory for one reason or another - say, an OpenGL view that has a bunch of textures loaded into it - that you will need to destroy or at least clean up in the case of a low memory warning. If that is the case, do this in your view controller:

- (void)didReceiveMemoryWarning
{
     [super didReceiveMemoryWarning];
     if([self isViewLoaded] && ![[self view] window]) {
          [self setView:nil];
     }
}

But you shouldn’t have to do this unless you have a really wacky view.


#5

Thanks Joe!


#6

FWIW: Apple’s API documentation on ViewDidUnLoad method shows ViewDidUnload as being deprecated.


#7

Thanks much Joe.