01.02.2014 Views

Objective-C Fundamentals

Objective-C Fundamentals

Objective-C Fundamentals

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Responding to low-memory warnings<br />

195<br />

}<br />

cityMappings = nil;<br />

In this implementation, when the operating system requests additional memory to be<br />

freed, the RootViewController class releases the city mapping NSDictionary. This<br />

frees memory immediately, but before you next need to look up an image to display<br />

for a given city, you’ll have to re-create the dictionary and its contents. You’ll see how<br />

this scenario is handled by the existing source code in a minute, but let’s first investigate<br />

the implications of a comment inserted by the iPhone project templates.<br />

If you create a new project in Xcode and select the Navigation-based Application<br />

template, you may notice that it provides an override for the didReceiveMemoryWarning<br />

method. This default implementation doesn’t perform any additional functionality. It<br />

simply forwards the message onto the UIViewController superclass, but it does<br />

include a comment hinting at an important fact to remember. This comment and a<br />

related one in the viewDidUnload method are repeated here:<br />

didReceiveMemoryWarning<br />

// Releases the view if it doesn't have a superview.<br />

viewDidUnload<br />

// Release any retained subviews of the main view.<br />

// e.g. self.myOutlet = nil;<br />

These comments hint that the UIKit framework will cache views that are currently offscreen,<br />

such as when the user temporarily switches to another tab in a tab bar application<br />

or drills down to another view in a navigation-based application.<br />

When a view controller is initialized, it loads the associated view from a NIB file (or<br />

creates it from scratch via code). Once loaded, the view controller keeps the user<br />

interface controls in memory even if the view is temporarily moved offscreen.<br />

Keeping the view in memory is efficient from a performance perspective because it<br />

allows the view to be redisplayed without repeating the construction process, but it<br />

comes with a potential negative in the form of increased memory consumption. This<br />

is especially true if you have a deep hierarchy in a navigation-based UI or if you have<br />

many tabs with complex UI requirements that will cause a number of offscreen views<br />

to be cached.<br />

The UIKit framework is designed to cope with this scenario. It automatically<br />

changes its view-caching behavior whenever your application finds itself in a lowmemory<br />

situation. When a UIViewController receives a didReceiveMemoryWarning<br />

message, and the view it controls is currently offscreen (it doesn’t have a superview, or<br />

parent), the UIViewController sends the view a release message. In most cases, this<br />

is enough to cause the view to immediately become deallocated, and hence this feature<br />

reduces the amount of memory consumed by the application without affecting<br />

the visual appearance or behavior of what the user can currently see or interact with.<br />

This memory optimization, however, can be undone if your view controller keeps<br />

objects in the view alive because they haven’t yet been released. This is what is hinted<br />

at by the comment in viewDidUnload: "Release any retained subviews of the main

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!