文章来源: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的更多相关文章

  1. [Objective-C]__bridge,__bridge_retained和__bridge_transfer的意思,区别与使用

    使用ARC能帮我们减轻不少内存管理方面的负担,尤其是对用惯了Java的程序员来说.但是像我这种Java基础本身就不牢固,做了两年的iOS已经习惯手动管理内存的半吊子,使用ARC还是经常碰壁. 对于CF ...

  2. *浅解嵌入式中的BootLoader

    本文只作为本人学习过程中的记录及时不时的突发奇想偶记.鄙人菜鸟一只,文中如有错误或疏漏,若读者肯不吝赐教,在下感激零涕.文章一直不断更新中 一.何为Bootloader 在嵌入式系统中,Bootloa ...

  3. ARC中__bridge, __bridge__transfer, __bridge_retained 关系

    总结于 IOS Tuturial 中 ARC两章,详细在dropbox pdf 文档. Toll-Free Bridging 当你在 Objective-C 和 Core Foundation 对象之 ...

  4. Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

    Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...

  5. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  6. 浅谈C中的malloc和free

    转自http://bbs.bccn.net/thread-82212-1-1.html非常感谢作者 浅谈C中的malloc和free 在C语言的学习中,对内存管理这部分的知识掌握尤其重要!之前对C中的 ...

  7. 从最大似然到EM算法浅解

    从最大似然到EM算法浅解 zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习十大算法之中的一个:EM算法.能评得上十大之中的一个,让人听起来认为挺NB的. ...

  8. 详解Java中的clone方法

    详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...

  9. 面试-1-C#浅解

    面试-1   C#浅解众所周知c#是微软推出的一款完全没面向对象的编程语言,那么对象是什么?在现实生活中人们一提到对象首先想到的就是“情侣”!但是在我们的程序中对象是什么? 在程序中个能够区别于其他事 ...

随机推荐

  1. C++算术运算符与算术表达式

    基本的算术运算符 在本章中主要介绍算术运算符与算术表达式,赋值运算符与赋值表达式,逗号运算符与逗号表达式,其他运算符将在以后各章中陆续介绍. 常见算数运算符 运算符 说明 举例 + 加法运算符,或正值 ...

  2. python pyfits

    原链接:http://blog.sina.com.cn/s/blog_a046022d0101a48h.html,全文复制以备出错.   导入pyfits模块:import pyfits        ...

  3. 高级UIKit-10(UDPSocket)

    [day1201_UDPSocket]:utpsocket的使用 使用UDP网络传输,是一种无连接的传输协议,不安全,一般使用在监控视频中或QQ聊天中,该网络传输就向广播传播模式,一对多. 在ios中 ...

  4. getopt、getopt_long和getopt_long_only

    GNU/Linux的命令行选项有两种类型:短选项和长选项,前者以 '-' 作为前导符,后者以 '--' 作为前导符.比如有一个命令: $ myprog -a vv --add -b --file a. ...

  5. Windows Azure 安全最佳实践 - 第 7 部分:提示、工具和编码最佳实践

    在撰写这一系列文章的过程中,我总结出了很多最佳实践.在这篇文章中,我介绍了在保护您的WindowsAzure应用程序时需要考虑的更多事项. 下面是一些工具和编码提示与最佳实践: · 在操作系统上运行 ...

  6. Android基础总结(精华完整版)

    1. 前言 1.1. 什么是3G.4G Ÿ 第三代移动通信技术(3rd - Generation),速率一般在几百Kbps,较之前的2G和2.5G在数据传输速度上有很大提升. Ÿ 第四代移动通信技术( ...

  7. three.js 源代码凝视(十)Math/Line3.js

    商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发 ...

  8. 区间dp模型之括号匹配打印路径 poj(1141)

    题目链接:Brackets Sequence 题目描写叙述:给出一串由'(')'' [ ' ' ] '组成的串,让你输出加入最少括号之后使得括号匹配的串. 分析:是区间dp的经典模型括号匹配.解说:h ...

  9. SLF4J warning or error messages and their meanings(转)

    The method o.a.commons.logging.impl.SLF4FLogFactory#release was invoked. Given the structure of the ...

  10. Juuluu 旗下企业站点管理系统3.0.1公布!

    KgE金刚企业站点管理系统是广州聚龙软件为国内中小企业开发的一款企业站点管理系统,KgE採用可视化的标签模型,可在Dreamvear等网页编辑下可视化编辑,KgE使用javaeemsyqlyuijqu ...