关于什么是toll-free bridging在这里我就不进行解释了,这里只说一下几种casting的模式。
在进行toll-free bridging转换的时候,只有下面这3种模式:
- __bridge
- __bridge_retained(也可以使用CFBridgingRetain())
- __bridge_transfer(也可以使用CFBridgingRelease())
对于这几种模式的解释,文档里也是有的,但可能是我才疏学浅,看了几遍也没搞明白到底是什么意思,所以最后只有通过试验来了解在使用这几种关键字进行casting的时候,究竟会发生什么。
为了搞明白这些关键字的用途,我必须先搞明白为什么在casting的时候要用他们。首先,所有Core Foundation所建立的对象都必须手动管理其reference count(当然,也可以在建立之后通过casting转交给Cocoa Foundation pointer,来让ARC管理),其次ARC虽然是会自动管理object的释放,但它的内部原理依然是用的reference counting,那么由于在执行casting的时候,ARC并不知道是否应该为pointer所指的object增加或是减少reference count(或者既不增加也不减少),因此我们必须在代码中给出明确指示,而这个指示一共有3种,就是上面说的那3个关键字。下面就是这3个关键字所产生的作用的具体描述:
____bridge__. 当将 Cocoa Foundation pointer转换成Core Foundation pointer的时候,使用__bridge不会增加或减少pointer所指的对象的reference count. 而假如是将Core Foundation pointer转换成Cocoa Foundation pointer的时候使用__bridge的话,则会将pointer所指对象的reference count加1。
____bridge_retained__(也可以使用CFBridgingRetain()).只能在将Cocoa Foundation pointer 转换为Core Foundation的pointer时使用. 转换后,会将pointer所指object的reference count加1.
____bridge_transfer__(也可以使用CFBridgingRelease()). 只能在将Core Foundation的pointer转换为Cocoa Foundation的pointer时使用. 转换后,不会增加或减少pointer所指object的reference count.
事实上,使用这3种方法进行casting各有个的优点,这其实完全取决于你的爱好与编程风格。
__假如你希望完全分开管理Core Foundation所创建的object 与 Cocoa Foundation在ARC环境下所创建的object的释放问提的话,那么你就应该用____bridge. 因为在将Cocoa Foundation pointer转换成Core Foundation pointer的时候,object的reference count并不会变化,这样当Core Foundation使用完这个object的时候,并不需要担心release这个object的问题,这个object的reference count依然在ARC的控制之下。而当在将Core Foundation pointer转换成Cocoa Foundation pointer的时候,所指Object的reference count会增加1,但是由于是在ARC环境下,所以当Cocoa Foundation pointer使用完这个Object后,会自动将这个object 的reference count减去1,这样一增一减,则又持平了,所以也不会影响到Core Foundation部分的代码对这个object的管理。
__假如你希望将Core Foundation所建立的对象交给ARC进行管理,则在将Core Foundation pointer转换成Cocoa Foundation pointer的时候,就应该使用____bridge_transfer。比如下面这个例子:
CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
// casting的时候加上__bridge_transfer,所指对象的reference count不会变
uuid = (__bridge_transfer NSUUID*)newUniqueID;
// 由于uuid是属于ARC管理,在将pointer设为nil后,其所指对象的reference count会自动减1
// 也就是会变为0,这样就释放了。
uuid = nil;
__最后,假如你希望将 Cocoa Foundation所建立的对象交给Core Foundation进行手动reference count管理,则在将Cocoa Foundation pointer转换成Core Foundation pointer的时候,则可使用__bridge_retained。