Eric L
Eric L

Reputation: 640

@autorelease directive and exception handling

- (void)foo
{
    @try {
         for (id o in os){
             @autoreleasepool {
                 for (id o2 in moreOs){
                       // create a lot of autoreleased objects.
                 }
                //exception raised
            }
        }

    }
    @catch (NSException *exception) {
     // handle the exception   
    }
}
  1. Will the compiler rewrite the above code to drain the pool in the event of an exception or will it leak?

  2. If the compiler does rewrite it, how will it do it?

Upvotes: 2

Views: 1252

Answers (2)

Chris Wagner
Chris Wagner

Reputation: 21013

To address your question, no those objects created in that pool will effectively be leaked until some autoreleasepool further down the stack is drained. There may be no pool further down the stack except the main autoreleasepool for your app which may not get drained for some time.

Try the following to force the drain to happen when this method returns if an exception is caught.

- (void)foo
{
    @autoreleasepool {
        @try {
            for (id o in os){
                @autoreleasepool {
                    for (id o2 in moreOs){
                        // create a lot of autoreleased objects.
                    }
                    //exception raised
                }
            }

        }
        @catch (NSException *exception) {
            // handle the exception   
        }
    }
}

According to documentation, when the outermost autoreleasepool is drained it will drain any nested ones as well.

If you drain an autorelease pool that is not the top of the stack, all (unreleased) autorelease pools above it on the stack are drained (and all their objects sent appropriate release messages). If you neglect to send drain to an autorelease pool when you are finished with it (something not recommended), the pool is drained when one of the autorelease pools in which it nests is drained.

From the "Scope of Autorelease Pools and Implications of Nested Autorelease Pools" section in Advanced Memory Management Programming Guide

Upvotes: 2

Jim
Jim

Reputation: 73966

It will not drain the pool. From Transitioning to ARC Release Notes:

On entry, an autorelease pool is pushed. On normal exit (break, return, goto, fall-through, and so on) the autorelease pool is popped. For compatibility with existing code, if exit is due to an exception, the autorelease pool is not popped.

Upvotes: 4

Related Questions