迈克·阿什 说:
当 __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 以 +1 的 retainCount 开始。当它赋值给 value 时,CFStringRef 会再次保留,因为默认情况下,value
它是强引用的。这导致双重保留。在范围结束时,-release 被发送到value
,但没有其他东西可以平衡来自 CFPreferences* Copy *AppValue 的延迟保留,从而导致内存泄漏。
如何__bridge_transfer
避免双重保留?