views:

3733

answers:

5

I'm looking for a primary source (or a really good explanation) to back up the claim that the use of autorelease is dangerous or overly expensive when writing software for the iPhone.

Several developers make this claim, and I have even heard that Apple does not recommend it, but I have not been able to turn up any concrete sources to back it up.

SO references:
autorelease-iphone
Why does this create a memory leak (iPhone)?

Note: I can see, from a conceptual point of view, that autorelease is slightly more expensive than a simple call to release, but I don't think that small penalty is enough to make Apple recommend against it.

What's the real story?

+2  A: 

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.

e.James
Can someone please repost this as a separate answer so that I can mark it as the accepted answer, and we can all move on? :)
e.James
+5  A: 

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

TofuBeer
happy to help (gave me something to search for :-)
TofuBeer
What they fail to mention is a lot of the classes in Foundation call autorelease on the objects they manage and thus in tight loops you need to create and manage your own autorelease pools if you are processing even a modest amount of data.
rpetrich
I don't think it's overhead in maintaining the pool; rather, it's best not to have memory allocated but not used any longer than necessary in a memory constrained environment. Autorelease leaves memory allocated longer than necessary.
Paul
@Paul, Yeah I thought about that last night on my way home... and then guess I forgot to about updating my answer - good catch.
TofuBeer
A: 

I would highly suggest avoiding autorelease like the plague. Memory management bugs are a great way to waste massive amounts of time and money, I've had the dubious honor of going through the process many a time on old Mac apps, and the fact that the iPhone has tight memory constraints mean that you have to be extremely careful, or the app will just be unstable and crash often...like so many of the first apps that were released last summer.

The only reliable way I've found to write stable iPhone applications is to manage all your memory yourself, and do it consistently. Even if you are the only programmer on your project, you'll thank yourself later. It can be difficult if you learned to program in languages that "take care of everything for you," but it really is worth learning how to do well if you are serious about createing quality iPhone apps.

ryan.scott
-1. You could certainly say it's somewhat less efficient, but autorelease does not create bugs. If you follow the memory management rules (which include autorelease), you won't have memory bugs. If you don't follow the rules, manually releasing things won't save you.
Chuck
+4  A: 

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.

Jon Thomason
+3  A: 

I tend to avoid using autorelease on the iPhone where I can (as Jon points out, you can't always do without it), simply because I like to know that the objects I'm working with are released the instant I don't need them. Memory constraints are one of the largest problems you'll face on the device and I believe they're the source of most of the crashing issues you'll find out there.

As highlighted by Apple, a particular area of concern is when you use autoreleased objects within any kind of loop, because they'll pile up within the autorelease pool. You then have to manage when to drain the pool or create / release one. Doing that every pass through the loop might degrade performance, but going too many passes without could lead to dangerous memory usage. I'm still tweaking this in Molecules, because there are intermittent memory issues when importing large (>2 MB) text files from the Protein Data Bank. I was able to improve performance by minimizing autoreleased objects, but couldn't eliminate them completely.

Another area to watch out for is using autoreleased objects with threads. If at all possible, do not use autoreleased objects when dealing with methods performed on a background thread, because the pool can be drained at random times. This leads to intermittent crashes that can be really fun to track down.

Brad Larson