浅解ARC中的 __bridge、__bridge_retained和__bridge_transfer

浅解ARC中的 __bridge、__bridge_retained和__bridge_transfer,第1张

概述文章来源:http://www.outflush.com/2015/03/introduction-of-arc-bridge-type-transfer/ 在对 bridge 相关的修饰符讲解前,首先了解以下内容 Core Foundation 是一组C语言接口,它与Foundation为相同功能提供接口,只是Foundation框架提供的是Objective-C接口。 Core Foundat

文章来源:http://www.outflush.com/2015/03/introduction-of-arc-bridge-type-transfer/

在对 brIDge 相关的修饰符讲解前,首先了解以下内容

Core Foundation 是一组C语言接口,它与Foundation为相同功能提供接口,只是Foundation框架提供的是Objective-C接口。 Core Foundation中的对象也存在引用计数的概念,类似于Foundation的retain/release,其对应的接口是CFRetain/CFRelease 这两个框架的对象之间可以相互转换,这种转换被称之为Toll-Free brIDge 当使用ARC时,Core Foundation中的对象不被ARC所管理,所以Core Foundation和Foundation中的对象在相互转换的过程中会涉及到对象所有权的转换,这里便用到了brIDge修饰符。 普通对象与C语言指针之间的转换
voID *p = NulL;{ID obj = [[NSObject alloc] init];p = (__brIDge voID *)obj;}NSLog(@"Hello");// 这里会出现错误NSLog(@"%@",[(__brIDge ID)p class]);

上面代码中的obj被ARC管理,p是一个C语言指针,不在ARC的管理范围中。当程序执行到obj的作用域之外,ARC便将obj给release掉,这时p指针成为NulL。所以在使用__brIDge的时候必须清楚对象的生命周期否则便会出现类似上面的错误。

这时便应该使用__brIDge_retain关键字来进行转换

p = (__brIDge_retain voID *)obj;// 上面这段代码在非ARC的环境下可以表示为p = obj;[(ID)p retain];

所以当obj被ARC release后,p指针仍然指向一个有效的对象。

而__brIDge_transfer则是用于将一个通过__brIDge_retain转换得到的C语言指针重新转换为被ARC管理的普通对象。

ID obj = (__brIDge_transfer ID)p;// 用非ARC来表示就是ID obj = p;[obj retain];[(ID)p release];

可以看出,__brIDge_transfer将p指向的对象的所有权转移到了ARC管理的obj上。

当在ARC环境中声明 ID obj 时,默认是 strong 修饰符修饰的,所以ARC会自动对obj进行retain处理,所以说 __brIDge_transfer只做了release处理。
Core Foundation与Foundation普通对象之间的转换

从上面已经知道Core Foundation中的对象也存在引用计数的概念。当在非ARC环境下,Core Foundation对象和Foundation对象可以通过标准的C语言类型转换来进行转换(Toll-Free brIDge)。而当引入ARC后则需要brIDge来进行转换,因为你需要明确的告诉编译器如何处理对象的所有权。

例如:

Nsstring *str = [Nsstring stringWithFormat…];CFStringRef cfStr = (__brIDge CFStringRef)str;...CFRelease(cfStr);

这里str对象被ARC所管理,而cfStr并不在ARC的管理中,因为__brIDge只是单纯的进行了类型转换,所以当str被ARC release后,cfStr便成为了NulL。

而当上面这段代码使用__brIDge_retain进行转换后,cfStr便拥有了str对象的所有权,这时如果str被ARC release,cfStr仍然有效。然而又因为Core Foundation中的对象也存在引用计数概念,所以需要使用CFRelease()手动的对cfStr进行release *** 作。代码如下:

Nsstring *str = [Nsstring stringWithFormat…];CFStringRef cfStr = (__brIDge_retain CFStringRef)str;...CFRelease(cfStr);

至于__brIDge_transfer,从上文可以得知其用于将对象的所有权转移,所以CF(Core Foundation简写)对象在使用__brIDge_transfer转换为Foundation对象后被释放。

CFStringRef cfStr = CFStringCreate…();Nsstring *str = (__brIDge_transfer Nsstring *)cfStr;// 在非ARC环境下,上面这句等同于Nsstring *str = cfStr;CFRelease(cfStr);

实际上,在Core Foundation内部存在两个用于CF对象和Foundation对象转换的函数

CFTypeRef CFBrIDgingRetain(ID X) {return (__brIDge_retained CFTypeRef)X;}ID CFBrIDgingrelease(CFTypeRef X) {return (__brIDge_transfer ID)X;}

使用这两个函数同样可以进行两者对象之间的类型转换。

总结 brIDge 用于被ARC管理的对象和不被ARC管理的对象之间的转换 __brIDge 只负责单纯的类型转换,需要格外注意对象的生存周期。 __brIDge_retain 将被ARC管理的对象转换为不被ARC管理的对象的同时,将ARC管理的对象retain,使其部分成为不被ARC管理的对象(描述很不当,自行多揣摩)。 __brIDge_transfer 将不被ARC管理的对象转换为被ARC管理的对象的同时,将不被ARC管理的对象release。 总结

以上是内存溢出为你收集整理的浅解ARC中的 __bridge、__bridge_retained和__bridge_transfer全部内容,希望文章能够帮你解决浅解ARC中的 __bridge、__bridge_retained和__bridge_transfer所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1051769.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存