Question

Code:

@autoreleasepool {

        id __autoreleasing obj = nil;

        @autoreleasepool {
            obj = [[NSObject alloc] init];

            _objc_autoreleasePoolPrint();
        }

        NSLog(@"obj: %@", obj); // Error
        _objc_autoreleasePoolPrint();
    }

From Clang documentation:

For __autoreleasing objects, the new pointee is retained, autoreleased, and stored into the lvalue using primitive semantics.

Why obj is autoreleased in inner @autoreleasepool block not in outer?

Second example:

@autoreleasepool {

        id __weak obj = nil;

        @autoreleasepool {
            id __strong obj1 = [[NSObject alloc] init];
            obj = obj1;

            NSLog(@"obj: %@", obj); // <NSObject: 0x7857657>
            NSLog(@"obj retain count: %d", (int) _objc_rootRetainCount(obj1)); // 2

            _objc_autoreleasePoolPrint();
        }

        NSLog(@"obj retain count: %d", (int) _objc_rootRetainCount(obj)); // 1
        NSLog(@"obj: %@", obj); // (null)

        _objc_autoreleasePoolPrint();
    }

Why NSLog outputs "(null)" if retain count is 1?

Was it helpful?

Solution

Why obj is autoreleased in inner @autoreleasepool block not in outer?

The object is autoreleased in the assignment to obj (obj = [[NSObject alloc] init];), so it is put into the topmost (innermost) autorelease pool, and is released when that pool is drained (at the end of the @autoreleasepool block).

Why NSLog outputs "(null)" if retain count is 1?

_objc_rootRetainCount() is not a documented function. Apparently _objc_rootRetainCount(nil) evaluates to 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top