ARC与Toll-Free Bridging

Posted feng9exe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC与Toll-Free Bridging相关的知识,希望对你有一定的参考价值。

arc模块与mrc模块的沟通。

相当于程序的混编处理。

 

Toll-Free Briding保证了在程序中,可以方便和谐的使用Core Foundation类型的对象和Objective-C类型的对象。

 

There are a number of data types in the Core Foundation framework and the Foundation framework that can be used interchangeably. This capability, called toll-free bridging, means that you can use the same data type as the parameter to a Core Foundation function call or as the receiver of an Objective-C message. 

Toll-Free Briding保证了在程序中,可以方便和谐的使用Core Foundation类型的对象和Objective-C类型的对象。详细的内容可参考官方文档。以下是官方文档中给出的一些例子:

 

NSLocale *gbNSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];

CFLocaleRef gbCFLocale = (CFLocaleRef) gbNSLocale;

CFStringRef cfIdentifier = CFLocaleGetIdentifier (gbCFLocale);

NSLog(@"cfIdentifier: %@", (NSString *)cfIdentifier);

// logs: "cfIdentifier: en_GB"

CFRelease((CFLocaleRef) gbNSLocale);

 

CFLocaleRef myCFLocale = CFLocaleCopyCurrent();

NSLocale * myNSLocale = (NSLocale *) myCFLocale;

[myNSLocale autorelease];

NSString *nsIdentifier = [myNSLocale localeIdentifier];

CFShow((CFStringRef) [@"nsIdentifier: " stringByAppendingString:nsIdentifier]);

 

在MRC时代,由于Objective-C类型的对象和Core Foundation类型的对象都是相同的release和retain操作规则,所以Toll-Free Bridging的使用比较简单,但是自从加入后,类型的对象内存管理规则改变了,而依然是之前的机制,换句话说,不支持。

这个时候就必须要要考虑一个问题了,Core FoundationObjective-C,用哪一种规则来管理对象的内存。显然,对于同一个对象,我们不能够同时用两种规则来管理,所以这里就Objective-CARCCore FoundationMRC或者说要确定对象类型转换了之后,内存管理的ownership的改变。

If you cast between Objective-C and Core Foundation-style objects, you need to tell the compiler about the ownership semantics of the object using either a cast (defined in objc/runtime.h) or a Core Foundation-style macro (defined inNSObject.h)

于是苹果在引入ARC之后对Toll-Free Bridging的操作也加入了对应的方法与修饰符,用来指明用哪种规则管理内存,或者说是内存管理权的归属。

这些方法和修饰符分别是:

__bridge(修饰符)

只是声明类型转变,但是不做内存管理规则的转变。

比如:

@"Hello, %@!", name];

只是做了NSString到CFStringRef的转化,但管理规则未变,依然要用Objective-C类型的ARC来管理s1,你不能用CFRelease()去释放s1。

__bridge_retained(修饰符) or CFBridgingRetain(函数)

表示将指针类型转变的同时,将内存管理的责任由原来的Objective-C交给Core Foundation来处理,也就是,将ARC转变为MRC。

比如,还是上面那个例子

NSString *s1 = [[NSString alloc] initWithFormat:@"Hello, %@!", name];

CFStringRef s2 = (__bridge_retained CFStringRef)s1;

// do something with s2

//...

// 注意要在使用结束后加这个

我们在第二行做了转化,这时内存管理规则由ARC变为了MRC,我们需要手动的来管理s2的内存,而对于s1,我们即使将其置为nil,也不能释放内存。

等同的,我们的程序也可以写成:

NSString *s1 = [[NSString alloc] initWithFormat:@"Hello, %@!", name];

CFStringRef s2 = (CFStringRef)CFBridgingRetain(s1);

// do something with s2

//...

// 注意要在使用结束后加这个

__bridge_transfer(修饰符) or CFBridgingRelease(函数)

这个修饰符和函数的功能和上面那个__bridge_retained相反,它表示将管理的责任由Core Foundation转交给Objective-C,即将管理方式由MRC转变为ARC。

比如:

CFStringRef result = CFURLCreateStringByAddingPercentEscapes(. . .);

NSString *s = (__bridge_transfer NSString *)result;

//or NSString *s = (NSString *)CFBridgingRelease(result);

s;

这里我们将result的管理责任交给了ARC来处理,我们就不需要再显式地将CFRelease()了。

对了,这里你可能会注意到一个细节,和ARC中那个4个主要的修饰符(__strong,__weak,...)不同,这里修饰符的位置是放在类型前面的,虽然官方文档中没有说明,但看官方的头文件可以知道。小伙伴们,记得别把位置写错哦:)

技术图片

 

http://www.cnblogs.com/flyFreeZn/p/4264220.html

 

以上是关于ARC与Toll-Free Bridging的主要内容,如果未能解决你的问题,请参考以下文章

arc音频回传功能需要投影支持吗

Objective-c的内存管理MRC与ARC

iOS开发ARC内存管理技术要点

iOS 4 真的支持 ARC 吗? iOS 4.2 SDK 在链接时缺少与 ARC 相关的符号

内存管理-MRC与ARC详解

如何实现与 ARC 兼容的 Objective-C 单例?