当你在 Objective-C 和 Core Foundation 对象之间进行转换时,就需要使用 Bridge cast。
编译器必须知道由谁来负责释放转换后的对象,如果你把一个 NSObject 当
作 Core
Foundation 对象来使用,则 ARC 将不再负责释放该对象。但你必须明确
地告诉 ARC 你的这个意图,编译器没办法自己做主。同样如果你创建一个 Core
Foundation 对象并把它转换为 NSObject 对象,你也必须告诉 ARC占据对象的所
有权,并在适当的时候释放该对象。这就是所谓的 bridging
casts。
多数情况下,Objective-C 对象和 Core Foundation 对象之间互相转换时, 我们都应该使用__bridge。但是有时候我们确实需要给予 ARC 某个对象的所有权, 或者解除 ARC 对某个对象的所有权。这种情况下我们就需要使用另外两种 bridging casts:
-
__bridge_transfer:给予 ARC 所有权
-
__bridge_retained:解除 ARC 所有权
为了代码更加可读和容易理解,iOS 还提供了一个辅助函数: CFBridgingRelease()。函数所做事情和
__bridge_transfer 强制转换完全一
样,但更加简洁和清晰。CFBridgingRelease() 函数定义为内联函数,因此不会 导致额外的开销。函数之所以命名为 CFBridgingRelease(),是因为一般你会在需要使用 CFRelease()释放对象的地方,调用
CFBridgingRelease()来传递对象 的所有权
ARC 只能作用于 Objective-C 对象,不能释放 Core
Foundation 对象。
因此这里你仍然需要调用 CFRelease()来释放该对象。
__bridge_retained 则正好相反,假设你有一个 NSString 对象,并且要将
它传递给某个 Core
Foundation API,该函数希望接收这个 string 对象的所有
权。这时候你就不希望 ARC 也去释放该对象,否则就会对同一对象释放两次,而
且必将导致应用崩溃!换句话说,使用 __bridge_retained 将对象的所有权给
予 Core
Foundation,而 ARC 不再负责释放该对象。
总结:
-
使用 CFBridgingRelease(),从 Core Foundation 传递所有权给 Objective-C;
-
使用 CFBridgingRetain(),从 Objective-C 传递所有权给 Core Foundation;
-
使用__brideg,表示临时使用某种类型,不改变对象的所有权