码迷,mamicode.com
首页 > 其他好文 > 详细

ARC与Toll-Free Bridging

时间:2019-02-15 15:54:24      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:bridge   __bridge   url   type   gen   add   init   fst   内容   

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

标签:bridge   __bridge   url   type   gen   add   init   fst   内容   

原文地址:https://www.cnblogs.com/feng9exe/p/10383675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!