ARC 实例变量保留释放

Posted

技术标签:

【中文标题】ARC 实例变量保留释放【英文标题】:ARC instance variable retain release 【发布时间】:2014-03-06 16:37:29 【问题描述】:

如果我们有这样的 .h 文件:

@interface TestViewController : UIViewController 

    __weak NSObject *object;


@end

.m 文件中的方法如下:

- (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));

然后我们得到以下保留计数的输出:

1 2 1

我的问题是,为什么当“object”声明为“__weak”实例变量时,保留计数会增加到 2,而且“localObject”保留计数仍然为 1。 我认为这是因为 ARC 如何插入保留/释放,但我不确定。

【问题讨论】:

您可能会在这里找到答案:@Martin R 建议的***.com/a/4636477/1187415 CFGetRetainCount() 在所有方面都与 -retainCount 相同,包括无用。 【参考方案1】:

首先通常的免责声明:保留计数的绝对值不会告诉您任何有用的信息,有关更多信息,请参阅

http://whentouseretaincount.com When to use -retainCount?

现在在你的情况下,在行中

NSLog(@"%ld", CFGetRetainCount((__bridge CFTypeRef)object));

您读取了一个弱指针的值,Clang/ARC documentation 4.2 Semantics 对此进行了说明:

对于__weak对象,保留当前指针,然后释放 在当前完整表达式的末尾。

因此,对象的保留计数在传递给CFGetRetainCount() 时增加一。您也可以在生成的汇编代码中看到:

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

【讨论】:

以上是关于ARC 实例变量保留释放的主要内容,如果未能解决你的问题,请参考以下文章

[UINavigationController 保留]:发送到已释放实例的消息

属性存取直接访问实例变量

fobjc-arc 标志导致发送到已释放实例崩溃的消息

iOS:释放正在使用的对象 (ARC)

我应该在 dealloc 中释放实例变量和属性吗?

实例变量不保留值