文档章节

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

木木情深
 木木情深
发布于 2014/02/19 16:26
字数 720
阅读 48
收藏 2
点赞 0
评论 0

一、非ARC的内存管理


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

  1. //NSString 转 CFStringRef  

  2. CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string];  

  3. //...  

  4. CFRelease(aCFString);  

  5.   

  6.   

  7. //CFStringRef 转 NSString  

  8. CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault,  

  9.                                                   bytes,  

  10.                                                   NSUTF8StringEncoding);  

  11. NSString *aNSString = (NSString *)aCFString;  

  12. //...  

  13. [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. {  

  3.     [super viewDidLoad];  

  4.       

  5.     NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  

  6.     CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  

  7.       

  8.     (void)aCFString;  

  9.       

  10.     //正确的做法应该执行CFRelease  

  11.     //CFRelease(aCFString);   

  12. }  


程序没有执行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. {  

  3.     [super viewDidLoad];  

  4.       

  5.     NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  

  6.     CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  

  7.     aNSString = (__bridge_transfer NSString *)aCFString;  

  8. }  


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

  1. aNSString = (__bridge_transfer NSString *)aCFString;  

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


3. __bridge 

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


从OC转CF,ARC管理内存:

  1. - (void)viewDidLoad  

  2. {  

  3.     [super viewDidLoad];  

  4.       

  5.     NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  

  6.     CFStringRef aCFString = (__bridge CFStringRef)aNSString;  

  7.       

  8.     (void)aCFString;  

  9. }  



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

  1. - (void)viewDidLoad  

  2. {  

  3.     [super viewDidLoad];  

  4.       

  5.     CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);  

  6.     NSString *aNSString = (__bridge NSString *)aCFString;  

  7.       

  8.     (void)aNSString;  

  9.       

  10.     CFRelease(aCFString);  

  11. }  



本文转载自:http://blog.csdn.net/yiyaaixuexi/article/details/8553659

共有 人打赏支持
木木情深
粉丝 37
博文 189
码字总数 26451
作品 0
广州
程序员
IOS开发之__bridge,__bridge_transfer和__bridge_retained

from:http://blog.csdn.net/sanpintian/article/details/8139878 Core Foundation 框架 Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管......

心如明镜
2014/02/26
0
0
iOS引用转换:Foundation与Core Foundation对象互相转换(__CFNSString转NSString,void *转id等等)

1. 两个框架的基本知识 1.1 Foundation 框架名是,在Xcode新建工程时可以选择导入(其实会默认自动依赖好)。Foundation框架允许使用一些基本对象,如数字和字符串,以及一些对象集合,如数组,...

陈满iOS
05/10
0
0
ARC中__bridge, __bridge__transfer, __bridge_retaine

多数情况下,Objective-C 对象和 Core Foundation 对象之间互相转换时, 我们都应该使用bridge。但是有时候我们确实需要给予 ARC 某个对象的所有权, 或者解除 ARC 对某个对象的所有权。这种情况...

lingfeng72
2015/11/24
24
0
[Objective-C]__bridge,__bridge_retained和__bridge_t

使用ARC能帮我们减轻不少内存管理方面的负担,尤其是对用惯了Java的程序员来说。但是像我这种Java基础本身就不牢固,做了两年的iOS已经习惯手动管理内存的半吊子,使用ARC还是经常碰壁。 最近...

burning_oc
2015/11/30
64
0
__bridge,__bridge_retained和__bridge_transfer的区别与使用

bridge只做类型转换,但是不修改对象(内存)管理权; bridge_retained(也可以使用CFBridgingRetain)将Objective-C的对象转换为Core Foundation的对象,同时将对象(内存)的管理权交给我们...

tengyoou
2013/07/02
0
0
理解 iOS 的内存管理

引言: ARC的出生及成长背景 苹果在 2011 年的时候,在 WWDC 大会上提出了自动的引用计数(ARC)。ARC 背后的原理是依赖编译器的静态分析能力,通过在编译时找出合理的插入引用计数管理代码,...

满脸胡茬的小码农
2017/11/17
0
0
Core Foundation

Swift中的 Core Foundation 类型是一个成熟的类。当出现内存管理注释时,Swift 会自动地管理 Core Foundation 对象的内存,这其中包括你实例化了的 Core Foundation 对象。在 Swift 中,你可...

Ethan-GOGO
2016/01/04
53
0
《从零开始学Swift》学习笔记(Day 61)——Core Foundation框架之内存管理

原创文章,欢迎转载。转载请注明:关东升的博客 在Swift原生数据类型、Foundation框架数据类型和Core Foundation框架数据类型之间转换过程中,虽然是大部分是可以零开销桥接,零开销并不意味...

智捷课堂
2016/01/18
31
0
Objective-C自动引用计数ARC

写在前面 这篇文章是阅读 Transitioning to ARC Release Notes 的笔记。 主要内容是关于 ARC 的规则。 简介 Automatic Reference Counting(ARC) 作为一个编译工具,自动管理 Objective-C 对象...

JiandanDream
05/09
0
0
迁移至ARC版本说明(Transitioning to ARC Release Notes)

自动引用计数(ARC)是编译器的一个特色,提供了Objective-C对象的自动内存管理机制。比起不得不考虑retain和release操作,ARC让你更加专注于应用中那些有趣的代码,如对象图,对象关系。 摘要...

big军
2013/04/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vue-router懒加载

1. vue-router懒加载定义 当路由被访问的时候才加载对应组件 2. vue-router懒加载作用 当构建的项目比较大的时候,懒加载可以分割代码块,提高页面的初始加载效率。 ###3. vue-router懒加载实...

不负好时光
12分钟前
0
0
庆祝法国队夺冠:用Python放一场烟花秀

天天敲代码的朋友,有没有想过代码也可以变得很酷炫又浪漫?今天就教大家用Python模拟出绽放的烟花庆祝昨晚法国队夺冠,工作之余也可以随时让程序为自己放一场烟花秀。 这个有趣的小项目并不...

猫咪编程
14分钟前
0
0
SpringBoot | 第七章:过滤器、监听器、拦截器

前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏高词汇、访问权限控制(URL级别)等业务需求。这些对于业务来说一般上是无关的,业务方是无需...

oKong
27分钟前
4
0
存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储

存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储 存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储。 顺序结构和链接结构适用在内存结构中。 顺序表每个单元都是按物理...

DannyCoder
38分钟前
1
0
Firefox 61已经为Ubuntu 提供支持

最新和最好的Mozilla Firefox 61 “Quantum”网络浏览器已经为Ubuntu Linux操作系统的用户提供了支持,现在可以通过官方软件库进行更新。 Mozilla于2018年6月26日发布了Firefox 61版本,该版...

六库科技
今天
0
0
Win10升级后执行系统封装(Sysprep)报错

开始封装 一年多以前开始给公司封装Win10系统,便于统一给公司电脑初始化携带各种软件的系统,致力于装完既可以开发的状态。那时候最新的版本是Win10 1703版本,自然就以他为母盘,然后结合V...

lyunweb
今天
40
0
php 性能优化

#什么情况下会遇到性能问题 PHP 语法使用的不恰当

to_be_better
今天
0
0
Jenkins 构建触发器操作详解

前言 跑自动化用例每次用手工点击jenkins出发自动化用例太麻烦了,我们希望能每天固定时间跑,这样就不用管了,坐等收测试报告结果就行。 一、定时构建语法 * * * * * (五颗星,中间用空格隔...

覃光林
今天
0
0
IDEA配置技巧

超详细设置Idea类注释模板和方法注释模板 idea去掉注解param下划线 JetBrains全系列破解

AK灬
今天
0
0
rsync通过服务同步/Linux系统日志/screen工具

rsync通过服务同步 分为服务端(机器A) 和客户端(机器B) 机器A操作编辑/etc/rsyncd.conf配置文件 [root@yolks1 ~]# vim /etc/rsyncd.conf 文件中添加以下配置 port=873 ...

Hi_Yolks
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部