Why is autorelease especially dangerous/expensive for iPhone applications? Why is autorelease especially dangerous/expensive for iPhone applications? objective-c objective-c

Why is autorelease especially dangerous/expensive for iPhone applications?


(cannot accept your own answer?)

Well, after all that, I did manage to find a reference from Apple Developer, added as a side-note near the bottom of the page:

iPhone OS Note: Because on iPhone OS an application executes in a more memory-constrained environment, the use of autorelease pools is discouraged in methods or blocks of code (for example, loops) where an application creates many objects. Instead, you should explicitly release objects whenever possible.

Still, this suggests using autorelease carefully, not avoiding it altogether.

(and now for my comment)

It sounds like there is a certain amount of overhead in maintaining the pool. I read this article which would lead me to probably avoid autorelease as much as possible because I prefer things to be consistent. If you have some memory under autorelease and other memory being totally manually managed it can be a bit more confusing.


It is not the question to use or not to use autorelease, because in some cases autorelease is the only way you'll get through. The question should be "Why not to use autorelease on all objects, instead of using retain and release?".

To answer that, you should first learn what's a proper use for autorelease. Let's say that you have a class that has two properties: firstName and lastName. There is a getter and a setter for each. But you also need a method that would return fullName, by concatenating these two strings into a brand new string:

- (NSString *) fullName {   NSString str = [[NSString alloc]initWithFormat:@"%@ %@", firstName, lastName];   // this is not good until we put [str autorelease];   return str;}

What's wrong with that picture? The reference count on the returned string is 1, so if you don't want to leak, the caller should release it when he's done. From the caller's point of view, he just requested a property value fullName. He is unaware of the fact that he got a brand new object that he should release after usage, and not some reference to an NSString internally held by the class!

If we put the [str release] before return, the string would be destroyed and the method would return garbage! That's where we use [str autorelease], to mark the object for release at a later time (typically when the event processing is done). That way the caller gets his object, and does not have to worry whether he should release it or not.

The convention is to call autorelease on a new object before the method returns it to the caller. Exceptions are methods with names that start with alloc, new or copy. In such cases the callers know that a brand new object is created for them and it is their duty to call release on that object.

Replacing release with autorelease altogether is a bad idea, since the objects would pile up and clog the memory very quickly, especially in loops. The resources on the iPhone are limited, so in order to minimize memory hogging, it is your duty to release the object as soon as you're done with it.


I disagree that avoiding autorelease altogether is wise.

Cocoa Touch uses it quite frequently internally and for many situations it's the only way to allocate memory properly (a good example is reusable table view cells). If you understand what is happening, the autorelease pool is a great tool at your disposal. The main thing to remember is that the blocks are not freed until some point later in the run loop. If you are running a tight loop without user interaction and are piling up autorelease blocks, you will eventually run out of memory.

Autorelease is not a substitute for garbage collection (not available on in the iPhone SDK) and can lead to nasty dangling pointer bugs (the pointer still seems to be good, then at some unpredictable point goes invalid), but is also very useful in writing clear and easy to maintain code. Consider the following case:

[aDictionary writeToFile:     [documentsDirectory stringByAppendingPathComponent:@"settings.plist"]              atomically:YES];

The path string is generated as an autorelease object. We aren't required to create a temporary object, so we avoid that overhead (and the possibility we might forget to release it). The memory will be fully released (no leaks), just that it will happen later in the run loop. Ask yourself: am I going to allocate hundreds of these before I get back to user input? If no (as would be the case here), autorelease is a great solution and indeed this NSString method for working with paths is only available using autoreleased memory.

I do agree with the above poster that following convention and being consistent is a very good idea.