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.
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.