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

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

[objc] view plaincopy
  1. CFStringRef aCFString = (CFStringRef)aNSString;
  2. NSString *aNSString = (NSString *)aCFString;

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

一、非ARC的内存管理

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

[objc] view plaincopy
  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或者相关方法手动来释放对象。
来看个例子:
[objc] view plaincopy
  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 的宏方法,下面两行代码等价:
[objc] view plaincopy
  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来管理内存,无需手动管理,也不会出现内存泄漏:
[objc] view plaincopy
  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的宏方法,下面两行代码等价:

[objc] view plaincopy
  1. aNSString = (__bridge_transfer NSString *)aCFString;
  2. aNSString = (NSString *)CFBridgingRelease(aCFString);

3. __bridge

__bridge 只做类型转换,不改变对象所有权,是我们最常用的转换符。

从OC转CF,ARC管理内存:
[objc] view plaincopy
  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管:

[objc] view plaincopy
  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);

转载于:https://www.cnblogs.com/Camier-myNiuer/p/4165465.html

Objective-C 和 Core Foundation 对象相互转换的内存管理总结相关推荐

  1. .net core中的高效动态内存管理方案

    .net core在新增的System.Buffers中引入了一大堆高效内存管理的类,如span和memory.内存池.本文今天这里介绍一个高效动态内存访问方案. ReadOnlySequenceSe ...

  2. 浅谈对象生存期与内存管理(转)

    .net内存回收与Dispose﹐Close﹐Finalize方法       一. net的对象使用一般分为三种情况﹕ 1.创建对象       2.使用对象       3.释放对象 二.创建对象 ...

  3. 6-Qt6对象树及内存管理

    把类的对象组织成树形结构,这种树形结构也称为对象树,Qt 使用对象树来管理 QObject 及其子类的对象. 重要:当父对象析构的时候,这个列表中的所有对象也会被自动逐级析构. 如下图树形,当Pare ...

  4. AS3.0 对象键和内存管理

    如果将 myObject 用作 Dictionary 对象中的键,则会创建对原始对象的另一个引用.例如,下面的代码创建两个对象引用 (myObject 变量和 myMap 对象中的键): import ...

  5. Core Foundation框架

    转载自:http://blog.csdn.net/weiwangchao_/article/details/7744972 Core Foundation框架 (CoreFoundation.fram ...

  6. 【C++】对象实例化/成员函数/成员变量的内存管理

    文章目录 1. 对象实例化的内存管理 总结 2.C++成员函数在内存中的存储方式 3.C++类的实例化对象的大小之sizeof() 实例一: 实例二: 实例三: 实例四: 实例五: 实例六: 实例七: ...

  7. Foundation和Core Foundation掺杂使用桥接 Toll-Free Bridging

    在cocoa application的应用中,我们有时会使用Core Foundation(CF),我们经常会在Objective-C和CF之间进行转化.系统使用arc的状态下,编译器不能自动管理CF ...

  8. Core Foundation 与 cocoa Foundation框架区别

    Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...

  9. 使用Core Animation对象来实现动画

    转载保留原文地址:http://blog.csdn.net/kqjob/article/details/10417461,转载的 在iOS中如果使用普通的动画则可以使用UIKit提供的动画方式来实现, ...

  10. Gson 字符串与对象相互转换工具类

    import com.google.gson.Gson; import com.google.gson.GsonBuilder;import java.lang.reflect.Type; /*** ...

最新文章

  1. poi 合并单元格_POI数据获取脚本分享
  2. 与其焦虑成疾,不如静心学习
  3. 利用jdom生成XML文件
  4. linux 编译openmp,Linux 系统中OpenMP
  5. VB高效导入Excel2003和Excel2007文件到MSHFlexGrid控件显示
  6. SAP 外向交货的包装功能实现
  7. SAP Spartacus能够使用的theme
  8. 如何卸载自己手机上的APK文件程序
  9. 抽取JDBC工具类:JDBCUtils
  10. js渐渐入门之懒人框架- laz.js
  11. 2016年工作中遇到的问题11-20
  12. java utility工具类怎么导入_Utility.java
  13. Javaweb(二)制作调查问卷
  14. (已解决)spring-boot maven报错Project 'org.springframework.boot:spring-boot-starter-parent:2.2.0.RELEAS
  15. matlab中字体修改,matlab——修改图中字体
  16. 独立董事、内部董事、执行董事、外部董事、非执行董事概念
  17. 原生js调用手机拍照功能
  18. 三维重建KInectFusion 学习笔记
  19. 最简单日柱推算法_干支记日推算方法揭秘
  20. 提前做好网络安全分析,运维真轻松(一)

热门文章

  1. 共阳极数码管显示c语言,基于74HC595单片机驱动数码管设计
  2. flask和ajax实现前后端交互
  3. Verifying transaction: | WARNING conda.core.path_actions:verify(962): Unable to create environments
  4. python实现不使用额外空间去除重复元素
  5. python面向对象的编程_不会面向对象,肯定学不好Python!简易的面向对象攻略来啦...
  6. truffle部署到测试网rinkeby
  7. js 实现PHP中的in_array()
  8. 2021湖南高考成绩分段查询,2021年湖南高考成绩排名查询系统,湖南高考位次排名查询...
  9. 简述使jdbc连接mysql数据库_java中简述使用JDBC完成数据库操作的基本步骤。
  10. linux获取url中文内容_SEO站内内链优化 – URL优化,提高页面权重