I am a new to objective-c, and I know the basic memory management rules like when to retain
release
autorelease
. But I don't know when should I wrap my code into autorelease pool and why?
An autorelease pool stores objects that are sent a release message when the pool itself is drained. If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks.
Autorelease pool blocks provide a mechanism whereby you can relinquish ownership of an object, but avoid the possibility of it being deallocated immediately (such as when you return an object from a method).
As with other performance optimizations, you should generally only add additional autorelease pools to your code if you notice high memory usage and profiling (using Instruments, for example) leads you to additional autorelease pools as a solution.
That said, you can wrap code that creates a large number of temporary objects in a tight loop in an autorelease pool. The default autorelease pool is drained at the end of a run loop cycle. So, if you're creating lots of temporary objects in each iteration of a for loop in your code, the default autorelease pool won't be drained until after your entire loop has run, meaning all the temporary objects you create can add up to a high temporary memory usage (sometimes called the "high water mark"). You can wrap each iteration of the loop in an @autoreleasepool
to cause unneeded, autoreleased, temporary objects created in that loop iteration to be released sooner.
To extends the previous answers:
An auto-release pool is used to send a release
message automatically to objects added to it.
In a iOS or Cocoa program, an auto-release pool is automatically created on the main thread, and it's drained at the end of the run loop.
That said, an auto-release pool is mandatory when using auto-released objects on another thread.
So if you detach a thread to some method, then wrap your threaded code inside an auto-release pool. Otherwise, the auto-released objects created in the thread will just leak.
Another use of an auto-release pool is the optimization of parts of code that will use a lot of memory, so they are freed before the end of the run loop.
But it only concerns auto-released objects.
For instance:
- ( void )test
{
NSMutableArray * a = [ [ NSMutableArray alloc ] init ];
[ a release ];
}
No need for an auto-release pool here, as you don't have an auto-released object.
The a
variable will be freed immediately, as it was explicitly allocated, and released.
Now this:
- ( void )test
{
NSMutableArray * a = [ NSMutableArray arrayWithCapacity ];
}
Here you are using a convenience constructor, meaning you don't have the ownership on that object.
It also means the object was added to the current auto-release pool (if there's one).
So it will be freed when this auto-release pool is drained, so it might take some cycles...
If the portion of the code you are writing uses a lot of memory, you may use another auto-release pool, so your auto-released objects are freed when your method returns:
- ( void )test
{
@autoreleasepool
{
NSMutableArray * a = [ NSMutableArray arrayWithCapacity ];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With