7
votes

I was reading the ARC docs on the llvm site: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#autoreleasepool

..in particular about @autoreleasepool.

In lot of current implementation using NSAutoreleasePool, I see cases where the pool is drained periodically during a loop iteration - how do we do the same with @autorelease pool, or is it all done for us somehow under the hood?

Secondly, the docs state that if an exception is thrown, the pool isn't drained.... ok exceptions are by name exceptional, but if they do happen, you might like to recover without leaking a load of memory. The docs don't specify when these objects will be released.

Anyone got any info about these points?

2

2 Answers

9
votes

In lot of current implementation using NSAutoreleasePool, I see cases where the pool is drained periodically during a loop iteration - how do we do the same with @autorelease pool, or is it all done for us somehow under the hood?

In the same way, i.e., by cascading autorelease pools. For instance:

@autoreleasepool {
    …
    for (int i = 0; i < MAX; i++) {
        @autoreleasepool {
            …
        }
    }
    …
}

Secondly, the docs state that if an exception is thrown, the pool isn't drained.... ok exceptions are by name exceptional, but if they do happen, you might like to recover without leaking a load of memory. The docs don't specify when these objects will be released.

In most cases the program won’t be able to recover gracefully due to the peculiar nature of exceptions in Cocoa, so I’d say that leaking objects is a lesser problem. If an @autoreleasepool block is exited because of an exception, the corresponding autoreleased objects will only get released when one of the enclosing autorelease pools is popped. But you can, of course, place @try/@catch/@finally blocks inside the @autoreleasepool block to prevent this from happening.

2
votes

how do we do the same with @autorelease pool

Like this:

for (int i = 0; i < 10000; i++) {
    @autoreleasepool {
        // Do your work here
        ...
    }
}

Secondly, the docs state that if an exception is thrown, the pool isn't drained.... ok exceptions are by name exceptional, but if they do happen, you might like to recover without leaking a load of memory.

AFAIK this is not possible with ARC. ARC is not exception-safe at all. If an exception occurs, there is the possibility of non-recoverable memory leaks. Code that uses ARC should not rely on exceptions for error reporting. The expectation is that the process crashes anyway when an exception is raised.