IOS - Foundation和Core Foundation掺杂使用桥接
Foundation和Core Foundation掺杂使用桥接 Toll-Free Bridging
在cocoa application的应用中,我们有时会使用Core
Foundation(CF),我们经常会在Objective-C和CF之间进行转化。系统使用arc的状态下,编译器不能自动管理CF的内存,这时候
你必须使用CFRetain和CFRelease来进行CF的内存的管理。
具体的CF内存管理规则见: Memory
Management Programming Guide for Core Foundation
在OC和FC之间进行转化的时候,主要是对象的归属问题。共有两种方式:
1、使用宏,可以标识归属者从OC到CF,还是从CF到OC。
NS_INLINE CFTypeRef CFBridgingRetain(id X) {
return (__bridge_retain CFTypeRef)X;
}
NS_INLINE id CFBridgingRelease(CFTypeRef X) {
return (__bridge_transfer id)X;
}
2、使用转化符,如:__bridge,__bridge_transfer,__bridge_retained
id my_id;
CFStringRef my_cfref;
…
NSString *a = (__bridge NSString*)my_cfref; // Noop cast.
CFStringRef b = (__bridge CFStringRef)my_id; // Noop cast.
…
NSString *c = (__bridge_transfer NSString*)my_cfref; // -1 on the CFRef
CFStringRef d = (__bridge_retained CFStringRef)my_id; // returned CFRef is +1
下面以详细的例子来介绍一下OC和CF在arc下内存管理的详细写法.下面以CFURLCreateStringByAddingPercentEscapes()函数为例说一下在ARC下的写法和非ARC下的写法。
非ARC模式下的写法:
#pragma mark – View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"=%@", [self escape:@"wangjun"]);
}
-(NSString *)escape:(NSString *)text
{
return (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"),
CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;
}
使用instruments检测,没有内存泄漏。

下面把上面工程改为arc模式。
可以看到xcode自动把上面函数转化为:
#pragma mark – View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"=%@", [self escape:@"wangjun"]);
}
-(NSString *)escape:(NSString *)text
{
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"),
CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;
}
在arc中,CF和OC之间的转化桥梁是 __bridge,有两种方式:
- __bridge_transfer ARC接管管理内存
- __bridge_retained ARC释放内存管理
上面的方法是从CF转化为OC NSString对象,使用的__bridge_transfer ,对象所有者发生转变,由CF到OC,最后由ARC接管内存管理。运行上面的代码,用instruments检测,是没有内存泄漏的。
上面代码等同于:
- (NSString *)escape:(NSString *)text
{
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)));}
如果将上述代码改为:
-(NSString *)escape:(NSString *)text
{
return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"),
CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;
}
编译也会成功,但是这时候用instruments检测,可以发现内存泄漏:

由于CF转化完OC,没有自己释放内存,同时也没有把内存管理交给ARC,所以出现内存泄漏。由于__bridge只是同一个对象的引用,内存的所有权没有发生变化。
下面在说一下oc到CF的转化,需要把OC的内存管理权释放掉。
NSString *s1 = [[NSString alloc] initWithFormat:@"Hello, %@!", name];
CFStringRef s2 = (__bridge_retained CFStringRef)s1;
// do something with s2 // . . .
CFRelease(s2);
最后由CF进行内存释放。
上面代码等同于:
CFStringRef s2 = CFBridgingRetain(s1);
// . . .
CFRelease(s2);
下面总结一下我们使用ARC情况下。oc和CF互相转化的原则:
- CF转化为OC时,并且对象的所有者发生改变,则使用CFBridgingRelease()或__bridge_transfer 。
- OC转化为CF时,并且对象的所有者发生改变,则使用CFBridgingRetain()或__bridge_retained
- 当一个类型转化到另一种类型时,但是对象所有者没有发生改变,则使用__bridge.
IOS - Foundation和Core Foundation掺杂使用桥接的更多相关文章
- IOS开发之—— Core Foundation对象与OC对象相对转换的问题
对ARC盲目依赖的同学: 1过度使用block后,无法解决循环引用问题 2遇到底层Core Foundation对象,需要自己手工管理它们的引用计数时,显得一筹莫展 first:对于底层Core Fo ...
- Foundation与Core Foundation内存管理基本原则简述
内存管理是一个十分重要的事情,稍有不慎就会发生内存泄漏或者是野指针的错误.内存泄漏一般表示没有任何指针指向的内存区域,由于这块内存在对象图中无法查找到,所以有可能永远都无法回收,如果内存泄漏的空间比较 ...
- Core Foundation框架介绍
Core Foundation框架介绍 **参考网址: ARC下OC对象和CF对象之间的桥接 Core Foundation框架介绍 Core Foundation框架 Core Foundation ...
- Core Foundation 官方文档翻译
Core Foundation框架中常用的隐含类型: 使用这些隐含类型时需要自己初始化,自己去释放内存.所以需要记住,在初始化的同时在相应位置释放.以防出现内存问题. 1.CFStringRe ...
- iOS-Core Foundation框架到Foundation桥接的三种方式
温故知新.勤总结,才能生巧!这次总结一下 :Core Foundation框架到Foundation桥接的三种方式 Foundation提供OC的基础类(像NSObject).基本数据类型等. Cor ...
- IOS之Core Foundation框架和Cocoa Foundation框架的区别
Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...
- IOS之Core Foundation框架和Cocoa Foundation框架的区别(转)
Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...
- Core Foundation框架
转载自:http://blog.csdn.net/weiwangchao_/article/details/7744972 Core Foundation框架 (CoreFoundation.fram ...
- Core Foundation 框架
Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...
随机推荐
- IIS 您要访问的网页有问题,无法显示!
提示:您要访问的网页有问题,无法显示.HTTP 500 – 内部服务器错误.”的问题解决方案! IIS服务器出现错误的原因很多,请尝试以下操作:1.查看网站属性——文档看看启用默认文档中是否存在:in ...
- 2013成都Regional:一块木板,几个气球
先来看木板: 再来看气球: 最后看木板+气球: google送的纪念品.... 到现在还没敢打乱: 赛场外面.... 赛场里面: 和比赛时出了问题,并现场换了一台的电脑(对面长安大学1队)... 最 ...
- oracle数据库表空间扩容方法
1. 先查询表空间在物理磁盘上存放的位置,注意使用sysdba的账号登陆. SELECT tablespace_name, file_id, file_name, ), ) total_space F ...
- Spak之开发代码 _pom 配置
1.spark on yarn import org.apache.spark.SparkContext import org.apache.spark.SparkContext._ /** * Cr ...
- 百度浏览器+hao123评价
1.用户界面: 界面比较简洁,没有多余的没用的东西.在界面上部有天气,比较方便用户查看天气,中间有各个实用性网站和大家通常使用较多的网站,可以比较快的查看.侧栏有些比较有针对性的内容.上部还有可以静音 ...
- scanf函数与输入缓冲区
本文链接:http://www.cnblogs.com/xxNote/p/4008668.html 今天看书的时候遇到scanf函数与缓冲区的问题,产生了一些猜想即:应该有一个指针来记录缓冲区中读取到 ...
- utils部分--一些通用的工具类封装
1.简介 utils部分是对一些常用的工具类进行简单的封装,使用起来比较方便.这里列举常用的一些. 2.ContextUtils使用 主要封装了网络判断.一些方法解释如下: ? 1 2 3 4 5 6 ...
- linux 学习之路
很多同学接触Linux不多,对Linux平台的开发更是一无所知. 而现在的趋势越来越表明,作为一个优秀的软件开发人员,或计算机IT行业从业人员, 掌握Linux是一种很重要的谋生资源与手段. 下来我将 ...
- OpenCV图像轮廓检测
轮廓检测: 轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点.那么就可以将中间的那一点去掉. 一.关键函数1.1 cvFindContours函数功能:对图像进行轮廓检测,这个函数将 ...
- (转)Singleton 单例模式(懒汉方式和饿汉方式)
原文地址:http://www.cnblogs.com/kkgreen/archive/2011/09/05/2166868.html 单例模式的概念: 单例模式的意思就是只有一个实例.单例模式确保某 ...