当在演员表中使用__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
如何避免双重保留?
答案 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