Question

When ARC enabled, following code causes the obj retained twice for the block by calling objc_retain() and objc_retainBlock().(So retainCount becomes 3 after the block definition.)

I checked that obj is not in autorelease pool and there are two objc_release() calls for obj at the end of the method. (I know counting retains does not make sense but i am checking the objc_retain() calls, not barely checking retain counts.) What is the rationale behind this?

-(void)myMethod
{
        NSObject *obj = [[NSObject alloc] init];
        NSLog(@"obj %@ retaincount %ld", obj, CFGetRetainCount((__bridge CFTypeRef)obj));
        void (^myBlock)(void) = ^() 
        {
            NSLog(@"obj %@ retaincount %ld", obj, CFGetRetainCount((__bridge CFTypeRef)obj));            
        };
        NSLog(@"obj %@ retaincount %ld", obj, CFGetRetainCount((__bridge CFTypeRef)obj));    
        myBlock();
}

Isn't it enough to retain the obj just once for capturing it by the block?

Note: Also, when i remove the myBlock variable and the call for it, so just with ^() {...} definition and that definition could never be called, obj is still retained with objc_retain() which seems weird. I am using XCode 4.3.2.

Was it helpful?

Solution

www.whentouseretaincount.com -- i.e. don't use retainCount as it'll cause nothing but confusion. Even for learning the innards.

If you want to know how and when blocks retain objects, you should look at the compiler, runtime, and blocks runtime sources. All are available.

A block may or may not retain an object. Specifically, a block may only retain an object when the block is copied (as long as the object reference isn't __weak).

Similarly, but orthogonally, ARC's retain/release behavior changes based on the optimization level of the compiler. In particular, DEBUG (-O0) code tends to have lots of retain/release. -Os (optimized) code will have many of these optimized out.

OTHER TIPS

Please read this: http://whentouseretaincount.com/

You shouldn't use retain count, the apple developers who wrote it advise against it, a lot of smart people advise against it and i'm telling you not to use it.

As for retain cycles its good practice to have a weak property outside of your block scope as such:

__weak typeof(obj) weakObj = obj;
void (^block)(void) = ^{
  [weakObj method];
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top