If we have .h file like this:
@interface TestViewController : UIViewController {
__weak NSObject *object;
}
@end
and methods in .m file like this:
- (void)viewDidLoad {
[super viewDidLoad];
NSObject *localObject = [[NSObject alloc] init];
NSLog(@"%ld", CFGetRetainCount((__bridge CFTypeRef)localObject));
object = localObject;
NSLog(@"%ld", CFGetRetainCount((__bridge CFTypeRef)object));
NSLog(@"%ld", CFGetRetainCount((__bridge CFTypeRef)localObject));
}
Then we get the following output for retain count:
1
2
1
My question is why does the retain count gets incremented to 2 on "object" when it is declared as "__weak" instance variable, furthermore "localObject" retain count remains 1.
I think that's because of how ARC inserts retain/release but I am not sure.
First of all the usual disclaimer: the absolute value of the retain count does not tell you anything useful, for more information see
- http://whentouseretaincount.com
- When to use -retainCount?
Now in your case, in the line
NSLog(@"%ld", CFGetRetainCount((__bridge CFTypeRef)object));
you read the value of a weak pointer, and the Clang/ARC documentation 4.2 Semantics states about that:
For __weak
objects, the current pointee is retained and then released
at the end of the current full-expression.
Therefore the object's retain count is increased by one while passed to CFGetRetainCount()
. You can see that also in the generated assembly code:
movq %rbx, %rdi
callq _objc_retain
movq %rax, %rbx
.loc 1 21 0
movq %rbx, %rdi
callq _CFGetRetainCount
movq %r15, %rdi
movq %rax, %rsi
xorb %al, %al
callq _NSLog
movq _objc_release@GOTPCREL(%rip), %r12
movq %rbx, %rdi
callq *%r12