你是否也曾被 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:
    1. 不是所有的 Objective-C 和 Core Foundation对象都是可以直接转换(toll-free bridged)的。例如, CGImage 和 UIImage 就不能互相转换, CGcolor 和 UIColor 也不能。这里列出了所有能够相互转换的类型。
    2. __bridge 转换,不仅限于 Core Foundation,也用于 一些API 使用 的void * 类型的指针, 可以让你存放任何类型的引用。

原文地址:http://blog.csdn.net/zhuiyi316/article/details/23794471

总结很不错,怕作者删了,拷过来以记之

ARC 与非 ARC 之间那些的'祸害'的更多相关文章

  1. ARC 与非ARC 之间的转换,以及如何使一个项目中,ARC与非ARC共存

    1,非ARC 转 ARC的操作 XCode 的 Edit -- Refactor -- Convert to Object-C ARC (注意,一般在一个大项目中,很少直接使用此方法,其正确率有待考虑 ...

  2. 1.ARC和非ARC文件共存

    1.ARC和非ARC文件共存 项目->Build Parses->对应的类 1.1.新项目兼容老的非ARC:-fno-objc-arc 1.2.老项目兼容ARC:-fobjc-arc

  3. ios工程中ARC与非ARC的混合

    ARC与非ARC在一个项目中同时使用, 1,选择项目中的Targets,选中你所要操作的Target,2,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并 ...

  4. iOS: ARC和非ARC下使用Block属性的问题

    1. Block的声明和线程安全 Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非AR ...

  5. ARC简介以及工程中ARC与非ARC的混合

    Piosa 博客园 博问 闪存 首页 新随笔 联系 管理 订阅 随笔- 79  文章- 0  评论- 13    ARC简介以及工程中ARC与非ARC的混合   ARC与非ARC在一个项目中同时使用, ...

  6. (转)iOS 开发,工程中混合使用 ARC 和非ARC

    [前提知识] ARC:Automatic Reference Counting,自动引用计数 在开发 iOS 3 以及之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain. ...

  7. IOS ARC和非ARC文件混用

    ARC在SDK4.0的时候增加的,因为要和曾经的项目融合,就会有arc和非arc文件的混合. 当然,也就这两种情况: 1.自己的旧项目没有使用ARC,可是引入的第三方库却是使用了ARC的. 2.自己的 ...

  8. iOS 开发,工程中混合使用 ARC 和非ARC(转)

    [前提知识] ARC:Automatic Reference Counting,自动引用计数 在开发 iOS 3 以及之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain. ...

  9. ARC简介以及工程中ARC与非ARC的混合(转)

    ARC与非ARC在一个项目中同时使用, 1,选择项目中的Targets,选中你所要操作的Target,2,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并 ...

随机推荐

  1. SQL Server Database 维护计划创建完整的备份策略

    SQL Server的维护计划Maintenance Plan是一个非常实用的维护工具,可以完成大多数的数据库维护任务,通过对这些功能的封装,可以省去很多的代码编写时间.网络上完整介绍的不是很多,特此 ...

  2. MySQL - 问题集 - 触发器更新本表数据异常"Can’t update table ‘tbl’ in stored function/trigger because it is already used by statement which invoked this"

    如果你在触发器里面对刚刚插入的数据进行了 insert/update, 则出现这个问题.因为会造成循环的调用. create trigger test before update on test fo ...

  3. 疑问:line-height对非文字行内块的影响

    line-height:对子元素是非文字的行内块,表现出来的不是垂直居中.目前还不知道具体细节. 可以看出来两个东西不在一行.老师的解释是line-height对非文字元素解释不一样,但是我没懂细节. ...

  4. 开机自动启动Tomcat

    一.安装JDK和Tomcat 1,安装JDK:直接运行jdk-7-windows-i586.exe可执行程序,默认安装即可. 备注:路径可以其他盘符,不建议路径包含中文名及特殊符号. 2.安装Tomc ...

  5. XVI Open Cup named after E.V. Pankratiev. GP of SPB

    A. Bubbles 枚举两个点,求出垂直平分线与$x$轴的交点,答案=交点数+1. 时间复杂度$O(n^2\log n)$. #include<cstdio> #include<a ...

  6. 【BZOJ】3309: DZY Loves Math

    题意 \(T(T \le 10000)\)次询问,每次给出\(a, b(1 \le a, b \le 10^7)\),求 \[\sum_{i=1}^{a} \sum_{j=1}^{b} f((i, j ...

  7. 实现倒计时功能js

    <p>系统将会在<strong id="endtime"></strong>秒后跳转到登录页!</p> [原生js实现] <s ...

  8. jQuery实现全选效果【转】

    这是一段用jquery实现全选的代码,主要思路如下: 1.所有的复选框都有单击事件,所有效果都是在单击事件下实现的 2.全选复选框所实现的功能与其他复选选项实现的功能不同,所有在单击事件内做一个判断, ...

  9. How to parse HTML page data in Windows Phone

    1. Navigate to page WebBrowser control browser.Navigate(new Uri("http://www.xxxx.com")); 2 ...

  10. C++标准库 -- tuple

    头文件:<tuple> 可访问属性: 无(用get方法来访问数据) 可访问方法: swap(tuple) 和另外一个tuple交换值 其他相关方法: swap(t1, t2) 交换两个tu ...