本文转载至 http://blog.csdn.net/allison162004/article/details/38756649

OS允许Objective-C 和 Core Foundation 对象之间可以轻松的转换,拿 NSString 和 CFStringRef 来说,直接转换豪无压力:

  1. CFStringRef aCFString = (CFStringRef)aNSString;
  2. NSString *aNSString = (NSString *)aCFString;

针对内存管理问题,ARC 可以帮忙管理 Objective-C 对象, 但是不支持 Core Foundation 对象的管理,所以转换后要注意一个问题:谁来释放使用后的对象。 本文重点总结一下类型转换后的内存管理。

一、非ARC的内存管理

倘若不使用ARC,手动管理内存,思路比较清晰,使用完,release转换后的对象即可。

  1. //NSString 转 CFStringRef
  2. CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string];
  3. //...
  4. CFRelease(aCFString);
  5. //CFStringRef 转 NSString
  6. CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault,
  7. bytes,
  8. NSUTF8StringEncoding);
  9. NSString *aNSString = (NSString *)aCFString;
  10. //...
  11. [aNSString release];

二、ARC下的内存管理

ARC的诞生大大简化了我们针对内存管理的开发工作,但是只支持管理 Objective-C 对象, 不支持 Core Foundation 对象。Core Foundation 对象必须使用CFRetain和CFRelease来进行内存管理。那么当使用Objective-C 和 Core Foundation 对象相互转换的时候,必须让编译器知道,到底由谁来负责释放对象,是否交给ARC处理。只有正确的处理,才能避免内存泄漏和double free导致程序崩溃。
根据不同需求,有3种转换方式
  • __bridge                  (不改变对象所有权)
  • __bridge_retained 或者 CFBridgingRetain()              (解除 ARC 所有权)

  • __bridge_transfer 或者 CFBridgingRelease()            (

    给予 ARC 所有权)

1. __bridge_retained 或者 CFBridgingRetain()

__bridge_retained 或者 CFBridgingRetain()  将Objective-C对象转换为Core Foundation对象,把对象所有权桥接给Core Foundation对象,同时剥夺ARC的管理权,后续需要开发者使用CFRelease或者相关方法手动来释放对象。
来看个例子:
  1. - (void)viewDidLoad  {
  2. [super viewDidLoad];
  3. NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
  4. CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
  5. (void)aCFString;
  6. //正确的做法应该执行CFRelease
  7. //CFRelease(aCFString);
  8. }
程序没有执行CFRelease,造成内存泄漏:
 
 
 
 
CFBridgingRetain()  是 __bridge_retained 的宏方法,下面两行代码等价:
  1. CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
  2. CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);

2. __bridge_transfer 或者 CFBridgingRelease()

__bridge_transfer 或者 CFBridgingRelease()  将非Objective-C对象转换为Objective-C对象,同时将对象的管理权交给ARC,开发者无需手动管理内存。
接着上面那个内存泄漏的例子,再转成OC对象交给ARC来管理内存,无需手动管理,也不会出现内存泄漏:
  1. - (void)viewDidLoad  {
  2. [super viewDidLoad];
  3. NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
  4. CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
  5. aNSString = (__bridge_transfer NSString *)aCFString;
  6. }

CFBridgingRelease() 是__bridge_transfer的宏方法,下面两行代码等价:

  1. aNSString = (__bridge_transfer NSString *)aCFString;
  2. aNSString = (NSString *)CFBridgingRelease(aCFString);

3. __bridge

__bridge 只做类型转换,不改变对象所有权,是我们最常用的转换符。
从OC转CF,ARC管理内存:
  1. - (void)viewDidLoad  {
  2. [super viewDidLoad];
  3. NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
  4. CFStringRef aCFString = (__bridge CFStringRef)aNSString;
  5. (void)aCFString;
  6. }

从CF转OC,需要开发者手动释放,不归ARC管:

  1. - (void)viewDidLoad  {
  2. [super viewDidLoad];
  3. CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);
  4. NSString *aNSString = (__bridge NSString *)aCFString;
  5. (void)aNSString;
  6. CFRelease(aCFString);

最新文章

  1. git 命令总结
  2. jquery each循环,
  3. freemarker初级教程(一)
  4. PYTHON 自动化学习之路
  5. 被解放的GPU CSS3动画加速
  6. SVG 使用
  7. 关于Eclipse 和 IDEA 导入library库文件 的步骤
  8. bundle install rake-10.4.2
  9. fedora21安装xmind7
  10. 在SurfaceView中自由书写和擦除
  11. NET Socket服务编程
  12. Ubuntu 下安装 nfs
  13. ToStringBuilder学习总结
  14. 小强的HTML5移动开发之路(10)——在线画板
  15. 【MySQL】redo log --- 刷入磁盘过程
  16. Python_day_01
  17. python算法练习
  18. python之tkinter使用-消息弹框
  19. .net mvc 列名 'Discriminator' 无效
  20. 【RF库Collections测试】Remove Values From List

热门文章

  1. Tomcat部署多个应用时日志文件路径相同引起的问题
  2. js获取页面传来参数的方法
  3. NeatBean下ssh 私钥格式问题
  4. idea 热部署
  5. winrm.cmd
  6. Splay树(多操作)——POJ 3580 SuperMemo
  7. gzip gunzip压缩保留源文件的方法:
  8. hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流
  9. springboot jpa | mybaits
  10. MySQL5.5中文支持