iOS 之bridge

在Cocoa应用程序中,我们常常会使用到Core Foundation对象,例如CFArrayRef 或者 CFMutableDictionaryRef等等,编译器不会自动管理Core Foundation对象的生命周期,你必须根据Core Foundation的内存管理规则来手动管理。

同时,我们经常又面临着CoreFoundation对象与Object-C对象的转换,在转换中用到的关键字就是bridge,如果使用不好会造成内存泄露,或者crash,设置直接编译不通过。下面描述一下bridge的概念和用法。

  • (和平转移)__bridge 转换Objective-C 和 Core Foundation 指针,不移交持有权.

  • (穿上铠甲)__bridge_retained 或 CFBridgingRetain 转换 Objective-C 指针到Core Foundation 指针并移交持有权。你要负责调用 CFRelease 或一个相关的函数来释放对象.

  • (卸下防备)__bridge_transfer 或 CFBridgingRelease 传递一个非Objective-C 指针到 Objective-C 指针并移交持有权给ARC。ARC负责释放对象。

第二种和第三种转交了所有权,即时用的的方式来管理计数引用,比如一个Core-Foundation对象用__bridge-transfer转换成了一个OC对象,那么就不需要再调用CFRelease来释放了,因为系统在检测到bridge-transfer关键字的时候可能就已经调用相应方法释放一次,再将所有权转给了OC,那么OC的ARC就可以接管一切了。

下面看几个例子:

  1. Core-Foundation与OC转换没有使用__bridge参数,编译器直接报错。


    image.png
  2. 将OC对象转成Core-Foundation,没有使用__bridge_retain转换持有权,结果超出OC的生命周期后运行时crash。
    应该改为 p=(__bridge_retain void*)obj;


    屏幕快照 2017-10-05 上午10.56.29.png
  3. 用__bridge_transfer 将Core-Foundation转成OC并转交控制权后,仍然一意孤行用老方法做CFRelease, 导致两次释放,最终crash。

image.png
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容