Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when should I wrap my code into autorelease pool

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?

like image 434
itenyh Avatar asked May 13 '12 16:05

itenyh


People also ask

How do Autorelease pools work?

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.

What does autorelease do?

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


2 Answers

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.

like image 76
Andrew Madsen Avatar answered Oct 18 '22 06:10

Andrew Madsen


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 ];
    }
}
like image 12
Macmade Avatar answered Oct 18 '22 07:10

Macmade