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.

188 CHAPTER 9 Memory management<br />

Be careful of macro optimizations<br />

When developing your application, be careful not to optimize for performance on a macro<br />

level. Although there are performance-based overheads to using an NSAutorelease-<br />

Pool, these overheads could be an insignificant factor in the overall performance of<br />

your application.<br />

It’s generally better to use performance-monitoring and analysis tools, such as those<br />

mentioned in chapter 14, to determine where the bottlenecks occur in your application’s<br />

performance than to apply general rules of thumb, such as “manual retain/<br />

release is more efficient than retain/autorelease.”<br />

inflating the memory consumption of your application. This may not be much of a<br />

problem on a desktop, but it can be a big problem on a memory-constrained device<br />

such as the iPhone. As an extreme case, consider the following code snippet:<br />

for (int i = 0; i < 100; i++) {<br />

for (int j = 0; j < 1000; j++) {<br />

NSString *msg = [[NSString alloc] initWithFormat:<br />

@"Message number %d is 'Hello, World!'",<br />

i * 1000 + j];<br />

[msg autorelease];<br />

}<br />

}<br />

NSLog(@"%@", msg);<br />

This code creates 100,000 string objects. At the end of each iteration through the<br />

inner loop, an additional string is added to the autorelease pool even though that<br />

string will never be referred to again by the code snippet. All 100,000 string objects<br />

will pile up in the pool, only to be released when the entire code snippet completes<br />

and returns to the application’s run loop. At least in theory…<br />

If you run this code snippet, you’ll probably find that your application crashes well<br />

before the 100,000th message is displayed with a message similar to the following:<br />

RentalManager (4888) malloc: *** mmap(size=16777216) failed (error code=12)<br />

*** error: can't allocate region<br />

*** set a breakpoint in malloc_error_break to debug<br />

This indicates that the <strong>Objective</strong>-C runtime attempted to allocate some memory for a<br />

new object but failed to find enough. This seems extreme considering the code interacts<br />

with only a single string at any given point in time.<br />

One solution is to explicitly create your own autorelease pool so you can release<br />

the string objects earlier, as demonstrated by the following code snippet:<br />

for (int i = 0; i < 100; i++) {<br />

NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];<br />

for (int j = 0; j < 1000; j++) {<br />

NSString *msg = [[NSString alloc] initWithFormat:<br />

@"Message number %d is 'Hello, World!'",

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

Saved successfully!

Ooh no, something went wrong!