ios 中__bridge,__bridge_transfer和__bridge_retained详解

转载自:http://www.cocoachina.com/industry/20130411/5975.html

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

发布于:2013-04-11 13:37阅读数:4109

iOS允许Objective-C 和 Core Foundation 对象之间可以轻松的转换,拿 NSString 和 CFStringRef 来说,直接转换毫无压力: [cpp] view plaincopyprint? 01. CFStringRef aCFString = (CFStringRef)aNSString; 02. NSString *aNSS

“”

阅读器

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

[cpp] view plaincopyprint?
01. CFStringRef aCFString = (CFStringRef)aNSString;  
02. NSString *aNSString = (NSString *)aCFString;

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

一、非ARC的内存管理

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

[cpp] view plaincopyprint?
01. //NSString 转 CFStringRef   
02. CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string];  
03. //...   
04. CFRelease(aCFString);  
05.  
06.  
07. //CFStringRef 转 NSString   
08. CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault,  
09.                                                  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或者相关方法手动来释放对象。

例子:

[cpp] view plaincopyprint?
01. - (void)viewDidLoad  
02. {  
03.     [super viewDidLoad];  
04.      
05.     NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  
06.     CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  
07.      
08.     (void)aCFString;  
09.      
10.     //正确的做法应该执行CFRelease   
11.     //CFRelease(aCFString);    
12.}

程序没有执行CFRelease,造成内存泄漏:

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

[cpp] view plaincopyprint?
01. CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  
02. CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);  

2. __bridge_transfer 或者 CFBridgingRelease()

__bridge_transfer 或者 CFBridgingRelease()  将非Objective-C对象转换为Objective-C对象,同时将对象的管理权交给ARC,开发者无需手动管理内存。

接着上面那个内存泄漏的例子,再转成OC对象交给ARC来管理内存,无需手动管理,也不会出现内存泄漏:

[cpp] view plaincopyprint?
01. - (void)viewDidLoad  
02. {  
03.     [super viewDidLoad];  
04.      
05.     NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  
06.     CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  
07.     aNSString = (__bridge_transfer NSString *)aCFString;  
08. }

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

[cpp] view plaincopyprint?
01. aNSString = (__bridge_transfer NSString *)aCFString;  
02. aNSString = (NSString *)CFBridgingRelease(aCFString);  
   
3. __bridge 

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

从OC转CF,ARC管理内存:

[cpp] view plaincopyprint?
01. - (void)viewDidLoad  
02. {  
03.     [super viewDidLoad];  
04.      
05.     NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  
06.     CFStringRef aCFString = (__bridge CFStringRef)aNSString;  
07.      
08.     (void)aCFString;  
09. }

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

[cpp] view plaincopyprint?
01. - (void)viewDidLoad  
02.   
03.     [super viewDidLoad];  
04.      
05.     CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);  
06.     NSString *aNSString = (__bridge NSString *)aCFString;  
07.      
08.     (void)aNSString;  
09.      
10.     CFRelease(aCFString);  
11. }

时间: 2024-08-26 06:57:35

ios 中__bridge,__bridge_transfer和__bridge_retained详解的相关文章

__bridge,__bridge_transfer和__bridge_retained详解

Core Foundation 框架Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的服务: 群体数据类型 (数组.集合等)程序包字符串管理日期和时间管理原始数据块管理偏好管理URL及数据流操作线程和RunLoop端口和soket通讯Core Foundation框架和Foundation框架紧密相关,它们为相同功能提供接口,但Foundation

iOS 中的 HotFix 方案总结详解

相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Apple) React Native(Facebook) JSPatch(Tencent) WaxPatch WaxPatch是一个通过Lua语言编写的iOS框架,不仅允许用户使用 Lua 调用 iOS SDK和应用程序内部的 API, 而且使用了 OC runtime 特性调用替换应用程序内部由 O

iOS中 三种随机数方法详解

ios 有如下三种随机数方法: 1 2 3 4 5 6 7 8 9 10 //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(time(0)); int i = random() % 5; //第三种 int i = arc4random() % 5 ; 注: ① rand()和random()实际并不是一个真正的伪随机数发生器,在使用之前需要先初始化随机种子,否则每次生成的随机数一

Swift使用WKWebView在iOS应用中调用Web的方法详解

这篇文章主要介绍了Swift使用WKWebView在iOS应用中调用Web的方法详解,使用WKWebView便等于使用和Safari中相同的JavaScript解释器,用来替代过去的UIWebView,需要的朋友可以参考下 自从iOS8开始,Apple引入了WKWebView欲代替UIWebView.相比而言,WKWebView消耗内从更少,功能也更加强大.让我们来看看WKWebView怎么使用吧! 0.初始化(1)首先需要引入WebKit库 复制代码代码如下: #import <WebKit/

&quot;MindManager&quot;学习iOS系列之&quot;CAAnimation-核心动画&quot;详解,让你的应用“动”起来。

"MindManager"学习iOS系列之"CAAnimation-核心动画"详解,思维导图内展示了CAAnimation-核心动画的大多数基本功能和知识,每个part都有代码讲解,展示出CAAnimation-核心动画的清晰轮廓,编者提供了"JPG"."SWF"."PDF"."Word"."Mmap"格式的源文件供给使用.注意:JPG格式仅为图片总览,SWF格式使用

IOS开发学习笔记(2)-----UIButton 详解

1. [代码][C/C++]代码     //这里创建一个圆角矩形的按钮    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];    //    能够定义的button类型有以下6种,//    typedef enum {//        UIButtonTypeCustom = 0,          自定义风格//        UIButtonTypeRoundedRect,        

css3中font-face属性的用法详解

@font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,你们当中或许有许多人会不自然的问,这样的东西IE能支持吗?当我告诉大家@font-face这个功能早在IE4就支持了你肯定会感到惊讶.我的Blog就使用了许多这样的自定义Web字体,比如说首页的Logo,Tags以及页面中的手写英文体,很多朋友问我如何使用,能让自己的页面也支持这样的自定义字体,一句话这些都是@fo

iOS企业证书网页分发全过程详解(图文并茂史无前例的详细哦)

iOS企业证书网页分发全过程详解 苹果的企业级证书发布的应用,是不用设备授权即可直接安装,并且不限设备上限.为了方便分发,苹果有协议实现通过网页链接直接下载安装企业级的应用. 首先需要说明它的原理:基本的原理就是在生成企业证书授权的ipa的同时,要生成一个对应的plist文件,plist文件中会配置ipa的下载地址.版本信息.Bundle ID 等信息,通过网页下载的时候其实下载的是这个plist文件,然后苹果通过自己的协议根据plist文件的配置信息去自动的下载安装app. 这里有个地址用来生

oc中字典的实现方法详解

一:字典的基本概念 Foundation中的字典(NSDictionary,NSMutableDictionary)是由键-值对组成的数据集合.正如,我们在字典里查找单词的定义一样. 通过key(键),查找的对应的value(值),key通常是字符串对象,也可以是其他任意类型对象.在一个字典对象中,key的值必须是唯一的. 此外,字典对象的键和值不可以为空(nil),如果需要在字典中加入一个空值,可以加入NSNull对象 二:不可变字典-NSDictionary 1:初始化(以一个元素和多个元素