__bridge_transfer的冲突描述;它会避免双重保留吗?

时间:2012-07-23 21:31:26

标签: objective-c ios automatic-ref-counting

迈克阿什说:

  

当在演员表中使用__bridge_transfer时,它告诉ARC该对象已被保留,并且ARC不需要再次保留它。由于ARC拥有所有权,因此它在完成后仍会释放。

Clang文档说:

  

(__ bridge_transfer T)op将必须具有不可保留指针类型的操作数强制转换为目标类型,该目标类型必须是可保留的对象指针类型。 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如何避免双重保留?

2 个答案:

答案 0 :(得分:1)

Clang的文件同意Mike Ash的观点。它表示它执行强制转换,并且该对象在范围的末尾被释放。演员阵容期间没有保留。

基本上,(__bridge_transfer T)会将值视为类型为T的已拥有值,就像调用[T new]将返回已拥有的类型{{}的值一样。 1}}。

答案 1 :(得分:0)

当你使用“transfer”时,ARC会减少对象在其执行结束时的保留计数 - 所以在这种情况下,你开始计数为1,“value”很强,所以它增加了计数,但是“转移”会导致减少,所以最终会以1结束。

NSString *value = (__bridge_transfer NSString *)CFStringCreateMutableCopy(NULL, 1000, CFSTR("Hello World") );
NSLog(@"value retainCount %ld", CFGetRetainCount((__bridge CFTypeRef)value));
NSLog(@"Value = %@", value);

2012-07-23 17:45:49.421 TimeTester [75918:f803] value retainCount 1 2012-07-23 17:45:49.423 TimeTester [75918:f803]价值= Hello World