你是否也曾被 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. 【康拓展开】及其在求全排列第k个数中的应用

    题目:给出n个互不相同的字符, 并给定它们的相对大小顺序,这样n个字符的所有排列也会有一个顺序. 现在任给一个排列,求出在它后面的第i个排列.这是一个典型的康拓展开应用,首先我们先阐述一下什么是康拓展 ...

  2. Requests库练习

    预备知识 字符串方法 用途 string.partition(str) 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把 字 符 串 string 分 成 一 个 3 ...

  3. [leetcode] 题型整理之数字加减乘除乘方开根号组合数计算取余

    需要注意overflow,特别是Integer.MIN_VALUE这个数字. 需要掌握二分法. 不用除法的除法,分而治之的乘方 2. Add Two Numbers You are given two ...

  4. JSON.parse()和JSON.stringify()区别

    parse用于从一个字符串中解析出json对象,如: var str = '{"name":"huangxiaojian","age":&q ...

  5. cve-2015-5122漏洞分析

    HackTem爆出的第二枚0day,分析了下,做个记录. Poc中一开始会分配一个Array类型的_ar结构. 第一次赋值 此时在a[0 ] –a[1e-1] 处已被赋值为Vector.<uin ...

  6. jQuery插件(cookie存值)

    使用cookie插件后,可以很方便地通过cookie对象保存.读取.删除用户的信息,还能通过cookie插件保存用户的浏览记录,它的调用格式为: 保存:$.cookie(key,value):读取:$ ...

  7. NOIP2009多项式输出(水)【A004】

    [A004]潜伏者[难度A]—————————————————————————————————————————————————————————————————————————— [题目要求] 一元 n ...

  8. pandas 学习(2): pandas 数据结构之DataFrame

    DataFrame 类型类似于数据库表结构的数据结构,其含有行索引和列索引,可以将DataFrame 想成是由相同索引的Series组成的Dict类型.在其底层是通过二维以及一维的数据块实现. 1.  ...

  9. python操作日期和时间的方法

    不管何时何地,只要我们编程时遇到了跟时间有关的问题,都要想到 datetime 和 time 标准库模块,今天我们就用它内部的方法,详解python操作日期和时间的方法.1.将字符串的时间转换为时间戳 ...

  10. zeppelin-0.6.0安装配置

    从http://zeppelin.apache.org/download.html 下载 zeppelin-0.6.0-bin-all.tgz 解压 修改zeppelin-site.xml,配置端口 ...