Home > Articles > Programming > C/C++

  • Print
  • + Share This
From the author of

Moving Autorelease into the Language

With ARC, the memory management semantics are now considered part of the language, rather than the standard library. Importantly, this includes autorelease pools. Most example code that you'll see will include something like:

int main(void)
{
    id pool = [NSAutoreleasePool new];
    // do some stuff
    [pool drain];
    return 0;
}

This pool catches any autoreleased objects and frees them just before the program exits. This simple bit of code, however, makes automatic reference counting difficult. Consider this function:

id example(void)
{
    id pool = [NSAutoreleasePool new];
    id tmp = somethingThatCreatesALotOfTemporaryObjects();
    [pool drain];
    return tmp;
}

Is this valid? It's difficult to tell. If the function that it calls returns an autoreleased object, then it isn't. The -drain message will (probably) cause the pool to free it, making tmp a dangling pointer. When you return it, the caller gets an invalid object. Irrespective of whether you're using ARC or not, you're now recommended to write this code as:

id example(void)
{
    id tmp;
    @autoreleasepool {
        tmp = somethingThatCreatesALotOfTemporaryObjects();
    }
    return tmp;
}

In non-ARC mode, this will generate exactly the same code, but it has the advantage that the lifetime of the autorelease pool is now explicit in the code, rather than needing to be inferred from the fact that the id-typed variable happens to be assigned from something that returns an autorelease pool instance. This means that the static analyzer can be a lot more confident about reporting errors related to autorelease pool usage.

If you compile with ARC enabled, then this is translated into calls to objc_autoreleasePoolPush() and objc_autoreleasePoolPop(). Autorelease pool objects are not allowed to be explicitly referenced by ARC code.

  • + Share This
  • 🔖 Save To Your Account