什么是Objective-C直接桥接
苹果公司为基于C语言的Core Foundation框架和基于Objective-C的Foundation框架中的许多数据类型提供了互用性。这种功能称为直接桥接,通过它你可以在Core Foundation 函数调用和Objective-C消息的接受器中使用数据类型相同的参数。你可以通过将一种数据类型转换为另一种数据类型,防止编译器报警。常用的直接桥接数据类型如下图,其中包括Core Foundation数据类型和对应的Foundation框架数据类型。
ARC下的桥接转换
在使用ARC时,通过ARC桥接转换可以直接桥接数据类型。这些操作必须将特殊标记__bridge,__bridge_retained,__bridge_transfer用作前缀。
__bridge
使用__bridge标记可以在不改变所有权的情况下,将对象从Core Foundation框架数据类型转换为Foundation框架数据类型(反之亦然)。换言之,如果你以动态方式创建了一个Foundation框架对象,然后(通过直接桥接)将它的数据类型转换为Core Foundation框架数据类型,那么通过__bridge标记可以使编译器知道这个对象的生命周期仍旧由ARC管理。反过来,如果你创建了一个Core Foundation框架数据类型的对象,然后将它的数据类型转换为Foundation框架的数据类型,那么通过__bridge标记可以告诉编译器这个对象的生命周期仍旧是以手动方式管理的(不是ARC管理的)。注意,使用该标记可以使编译器不报错,但是不会改变对象的所有权,因此使用它解决内存泄漏和悬挂指针问题时应多加小心。
__bridge_retained
使用__bridge_retained标记可以将Foundation框架数据类型对象转换为Core Foundation框架数据类型对象,并从ARC接管对象的所有权。这样你就可以手动管理直接桥接数据的生命周期。
__bridge_transfer
使用__bridge_transfer标记可以将Core Foundation框架数据类型对象转换为Foundation框架数据类型对象,并且会将对象的所有权交给ARC管理。这样就会由ARC管理对象的生命周期。
桥接转换标记的语法如下:
(桥接转换标记 目的数据类型)变量名
下面是示例代码:
第二个例子之所以使用__bridge_retained是因为如果直接用__bridge会有潜在的悬挂指针问题,因为在执行桥接转换时,ARC会立刻向该NSString对象(存储在greeting中)发送一条release消息。所以使用__bridge_retained,避免ARC向该对象发送release消息,但是同时我们也必须手动管理这个对象(已经转换为CFStringRef类型)的生命周期。
最后,可以通过Xcode中Product菜单中的Analyze选项来对demo的内存使用情况做简单检查。