Why is autorelease especially dangerous/expensive for iPhone applications?

Solution 1:

(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.

Solution 2:

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.