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的文件双击,并 ...
随机推荐
- Theano在windows下的安装及GPU加速
安装环境:wondows 64bit Teano安装测试 1. Anaconda 安装 Anaconda是一个科学计算环境,自带的包管理器conda很强大.之所以选择它是因为它内置了python,以及 ...
- 无法从“char*转换为“LPCWSTR”
解决办法: 第一种方法:工程属性->配置属性->右边 项目默认值->字符集 改为未设置 第二种:一般直接加个L在前面,当是字符串常量的时候可以这样,也可以_T(x)等 来自:软件 ...
- 弹性布局flex-兼容问题
这里弹性布局的用法就不说了 用过的都知道很方便 虽然现在弹性布局已经实现标准了 但是还是存在一些兼容问题 旧版本 (一些低版本的浏览器) display:-webkit-box; 新版本(目前的标准版 ...
- Python爬虫学习(2): httplib
httplib模块实现了HTTP和HTTPS的客户端部分,但是一般不直接使用,经常通过urllib来进行HTTP,HTTPS的相关操作. 如果需要查看其源代码可以通过查找命令定位: find / -n ...
- 【Redis】简介与安装
Linux 安装 [root@redis ~]# wget http://download.redis.io/releases/redis-2.8.19.tar.gz 解压缩redis[root@ha ...
- 基于socket的TCP和UDP编程
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- 【hihoCoder】1033: 交错和
初探数位dp 介绍了数位类统计的基础知识.以下列出其中的基础点: 基本问题 统计在区间[l, r]中满足条件的数的个数 思路 1. [l, r] 将问题转换为 在[0, r]中满足条件的个数 - 在[ ...
- 【noip 2004】 合并果子
noip2016结束后的第一份代码--优先队列的练习 合并果子 原题在这里 #include <iostream> #include <queue> #include < ...
- stl循环删除
struct st_data { st_data(int i) : id(i) {} int id; }; 对于STL标准序列容器vector/deque/list(以vector为例) 当我们需清空 ...
- ouath原理
1.OAuth的简述 OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是 ...