迈克·阿什说:__bridge_transfer的相关描述;它是否避免了双重保留?
当__bridge_transfer在铸造时,它告诉ARC这个对象已经保留,而ARC不需要再保留它。自从ARC获得所有权后,它在完成后仍会释放它。
锵文档说:
(__bridge_transfer T)运算连铸操作数,其必须具有非可保持指针类型,到目的地的类型,它必须是一个可保持对象指针类型。 ARC将在封闭的完整表达式的末尾释放该值,这取决于对本地值的通常优化。
没有在Clang文档中说它__bridge_transfer避免了双重保留。它只是表示该对象将在未来某个时间发布。
这是为什么?考虑以下代码片段:
NSString *value = (__bridge_transfer NSString *)CFPreferencesCopyAppValue(CFSTR("someKey"), CFSTR("com.company.someapp"));
CFStringRef从retainCount +1开始。将其分配给值时,CFStringRef会再次被保留,因为默认情况下,会强烈引用value
。这导致了双重保留。在范围的最后,一个-release被发送到value
,但是没有其他任何东西可以平衡CFPreferences * 复制 * AppValue的滞留,从而导致内存泄漏。
__bridge_transfer
如何避免双保留?
Clang的文档并不会说“当__bridge_transfer用于演员时,它告诉ARC此对象已被保留,并且ARC不需要再保留它“。这意味着存在一些内置智能,ARC认识到我们即将分配给强引用类型,并随后吃掉-retain消息以避免双重保留。它是否正确? – 2012-07-23 21:42:40
为了补充一点,是的,我同意在演员阵容上不会执行任何保留。但是在赋值为'value'时会出现保留。 – 2012-07-23 21:44:46
@nessup:我应该澄清一下:Clang文档明确声明该值将在完整表达式的末尾释放。这基本上意味着“这是一个拥有的价值”。演员阵容中没有保留,但之后有一个释放。随后分配给局部变量将保留第二次,但当该变量超出范围时也会有第二次释放。优化器将识别双重保留并将其删除,因此您将剩下一个保留(并且在该范围末尾有一个单独的版本)。 – 2012-07-23 22:08:45