ARC 与非 ARC 之间那些的'祸害'
你是否也曾被 assign、retain、copy、release、autorelease、strong、__strong、weak、__weak、__unsafe__unretain、__autoreleasing、__bridge、__bridge__transfer、__bridge__retained这些个 ARC 和非 ARC 之间的『祸害』搞的晕头转向,四肢无力,整个人都不好了。
好吧,是时候来个了断了。
一.认识到以下事实
- ARC 是 LLVM 3.0 编译器的一个新特性,它是编译时特性而不是运行时特性,它所做的事情其实就是编译程序的时候在以前需要手动管理内存的地方自动的为你添加retain 和 release。
- ARC 的性能优于手动内存管理。但是它只适用于 Objective-C 对象,而 iOS 中基于 C 语言的 API 会用到 Core Foundation对象(CFxxxx),对于这些 CF 对象,依然需要手动内存管理。
- ARC 是 Objective-C 的必然趋势,务必顺势而为。
二.assign、retain、copy、release、autorelease
- assign,直接赋值,适用于 Int、BOOL、Float 等基本数据类型。如果是用在 Objective-C对象(指针)身上,如 NSString *a=b,则表示a 同时指向 b 指向的那一块内存,但是引用计数不变。这样会导致如下问题:当 b 指向的内存被释放时,a 并不知情,a就成了野指针,程序崩溃。
- retain,用在Objective-C对象(指针)身上,赋值时指向同一块内存,引用计数加一。很明显,retain 不用于 Int、BOOL 等基本数据类型,也不能用于 CF 对象,原因在于这些根本就没有引用计数。
- copy,与 retain 的区别在于赋值时会重新开辟一块新的内存并复制。
- release,引用计数减一,当引用计数为0时就会释放掉对应的内存。
- autorelease,在 autorelease pool 中自动 release 对象。
三.Strong、weak、__Strong、__weak、__unsafe__unretained、__autoreleasing
- Strong,iOS5.0以及 Mac OS X10.7之后引入的新特性,也即是在新的 SDK 中用 Strong 和 weak 来表示强引用和弱引用。Strong 相当于前面的 retain。Strong 的含义是只要还有指针指向它,那么这个对象就一直活着,内存不会被释放。Strong 用于声明属性(property),而__Strong用于声明实例变量和局部变量,默认情况下实例变量和局部变量都是 strong 型的,所以你不需要再声明一遍。
- Weak,对应于之前的 assign,弱引用,如果指向的对象被释放,那么指针被置为 nil。__weak用于实例变量和局部变量。
- 在使用 strong 时,可能会导致retain cycle。例如,你拥有一个对象包含了另外了一个实例变量对象,但是第二个对象又把前一个对象作为它的委托,那么这两个对象将不会被释放。所以需要把 delegate 设为 weak。
- __unsafe__unretained,类似于__weak,差别在于,当所指向的对象被释放时,__unsafe__unretained 修饰的指针不会被置为nil 而会成为野指针,正如它的名字 unsafe 所暗示的。这是应该极力避免的。但为什么还要用__unsafe__unretained 呢,因为__weak 是 iOS5以后才出现的。
- __autoreleasing 的英文解释为:to denote arguments that are passed by reference (id *) and are autoreleased on return,即主要是在引用传参时使用。
四.__bridge、__bridge__transfer、__bridge__retained
- 在 Objective-C 对象和 CF 对象之间转换的时候需要用到 bridge cast.
- 当你要临时的使用一个类型,而不想要更改所有关系时, 你要使用 __bridge。转换值 = 原变量指针; (原变量如果释放, 转换值也就不能使用了)
- 当把所有关系从 Core Foundation 转换到 Objective-C 的时候, 你要使用 CFBridgingRelease(),也就是__bridge__transfer。把内存管理的权利从 CF 转交给 ARC。所有你调用名称含有 Create,Copy 或 Retain 的 Core Foundation 函数的地方, 你都必须使用 CFBridgingRelease() 来将返回值转移到 ARC 中。
- 当把所有关系从 Objective-C 转换到 Core Foundation 的时候,你要使用 CFBridgingRetain(),也就是__bridge__retained。把内存管理的权利从 ARC 转为 CF,这时需要手动内存管理也即是在使用完 CF 对象之后调用 CFRelease()。
- Notes:
- 不是所有的 Objective-C 和 Core Foundation对象都是可以直接转换(toll-free bridged)的。例如, CGImage 和 UIImage 就不能互相转换, CGcolor 和 UIColor 也不能。这里列出了所有能够相互转换的类型。
- __bridge 转换,不仅限于 Core Foundation,也用于 一些API 使用 的void * 类型的指针, 可以让你存放任何类型的引用。
原文地址:http://blog.csdn.net/zhuiyi316/article/details/23794471
总结很不错,怕作者删了,拷过来以记之
ARC 与非 ARC 之间那些的'祸害'的更多相关文章
- ARC 与非ARC 之间的转换,以及如何使一个项目中,ARC与非ARC共存
1,非ARC 转 ARC的操作 XCode 的 Edit -- Refactor -- Convert to Object-C ARC (注意,一般在一个大项目中,很少直接使用此方法,其正确率有待考虑 ...
- 1.ARC和非ARC文件共存
1.ARC和非ARC文件共存 项目->Build Parses->对应的类 1.1.新项目兼容老的非ARC:-fno-objc-arc 1.2.老项目兼容ARC:-fobjc-arc
- ios工程中ARC与非ARC的混合
ARC与非ARC在一个项目中同时使用, 1,选择项目中的Targets,选中你所要操作的Target,2,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并 ...
- iOS: ARC和非ARC下使用Block属性的问题
1. Block的声明和线程安全 Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非AR ...
- ARC简介以及工程中ARC与非ARC的混合
Piosa 博客园 博问 闪存 首页 新随笔 联系 管理 订阅 随笔- 79 文章- 0 评论- 13 ARC简介以及工程中ARC与非ARC的混合 ARC与非ARC在一个项目中同时使用, ...
- (转)iOS 开发,工程中混合使用 ARC 和非ARC
[前提知识] ARC:Automatic Reference Counting,自动引用计数 在开发 iOS 3 以及之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain. ...
- IOS ARC和非ARC文件混用
ARC在SDK4.0的时候增加的,因为要和曾经的项目融合,就会有arc和非arc文件的混合. 当然,也就这两种情况: 1.自己的旧项目没有使用ARC,可是引入的第三方库却是使用了ARC的. 2.自己的 ...
- iOS 开发,工程中混合使用 ARC 和非ARC(转)
[前提知识] ARC:Automatic Reference Counting,自动引用计数 在开发 iOS 3 以及之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain. ...
- ARC简介以及工程中ARC与非ARC的混合(转)
ARC与非ARC在一个项目中同时使用, 1,选择项目中的Targets,选中你所要操作的Target,2,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并 ...
随机推荐
- Oracle 11g RAC 卸载CRS步骤
Oracle 11g之后提供了卸载grid和database的脚本,可以卸载的比较干净,不需要手动删除crs ##########如果要卸载RAC,需要先使用dbca删除数据库,在执行下面的操作### ...
- [译]SSAS下玩转PowerShell(二)
上一篇中简单的介绍了SSAS下的PowerShell,这一篇会演示更多的操作,比如根据当前时间创建备份,使用变量去指定处理哪一个分区,以及用XMLA脚本去创建分区,和在PowerShell中调用Pow ...
- Kindle支持哪些格式
官方产品介绍页面有相关技术参数: Kindle Format 8 (AZW3), Kindle (AZW), TXT,PDF, MOBI, PRC原格式,HTML,DOC,DOCX,JPEG,GIF, ...
- 如何打开 系统信息窗体和 DirectX诊断工具
开始---运行----msinfo32.exe 运行 位于C:\Program Files\Common Files\Microsoft Shared\Msinfo\msinfo32.exe,显示计算 ...
- mac系统下mysql开机启动总是3307
修改了mysql的my.cnf可还是不行,启动后就是3307,必须关掉再启动. 觉得可能是mac系统在哪里写死了开机启动项. http://queforum.com/mysql/1012987-mys ...
- Block 使用注意点
Block 使用的注意点 block 一般用来传值的时候才调用 代理:一般用来封装控件的时候调用,这样有利于扩展 1.用Block 可以做通知的,什么时候需要的时候就什么时候调用.分为无返回值和有返回 ...
- linux系统网址
主站:http://www.xitongzhijia.net/linux/ linux:http://www.xitongzhijia.net/linux/201603/69275.html (7.2 ...
- *HDU 1054 二分图
Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- stl文件格式
http://wenku.baidu.com/view/a3ab7a26ee06eff9aef8077b.html [每个三角形面片的定义包括三角形各个定点的三维坐标及三角形面片的法矢量[三角形的法线 ...
- 谢欣伦 - OpenDev原创教程 - 本地IP查找类CxLocalHostIPAddrFind
这是一个精练的本地IP查找类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxLocalHostIPAddrFind的使用如下: ...