修饰符

ARC能够解决开发中大部分的的内存管理问题,但是另外还有一部分是需要开发者自己处理的.这主要就是与底层Core Foundation对象交互的那部分,底层的 Core Foundation 对象由于不在 ARC 的管理下,所以需要自己维护这些对象的引用计数。

ARC有效时,对象类型上必须附加所有权修饰符。所有权修饰符一共有4种:

  • __strong

  • __weak

  • __unsafe_unretained

  • __autoreleasing

__strong 修饰符

__strong修饰符表示对对象的强引用。持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用的对象会随之释放。

__strong修饰符是id类型和对象类型默认的所有权修饰符。id和对象类型在没有明确指定所有权修饰符时,默认为strong。它不仅仅适用于自己生成并持有的对象,非自己生成并持有的对象也适用,附有strong修饰符的变量可以相互赋值,在赋值上也能够正确的管理其对象的所有者。

当需要释放强引用指向的对象时,需要将强引用置nil。

weak 修饰符

strong可能会出现引用计数式内存管理中存在的“循环引用”问题。weak 修饰符就是为了解决循环引用的问题,它提供弱引用。弱引用不能持有对象实例,对象在被释放的同时,指向它的弱引用会将自动失效且会自动被置nil被赋值的状态。这样有效得防止无效指针、野指针的产生。__weak一般用在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编辑与生成的UI控件。

__unsafe_unretained 修饰符

__unsafe_unretained

ARC是在iOS 5引入的,而这个修饰符主要是为了在ARC刚发布时兼容iOS 4以及版本更低的设备,因为这些版本的设备没有weak pointer system,简单的理解这个系统就是我们上面讲weak时提到的,能够在weak引用指向对象被释放后,把引用值自动设为nil的系统。这个修饰符在定义property时对应的是"unsafe_unretained",实际可以将它理解为MRC时代的assign:纯粹只是将引用指向对象,没有任何额外的操作,在指向对象被释放时依然原原本本地指向原来被释放的对象(所在的内存区域)。所以非常不安全。

尽管ARC式的内存管理是编译器的工作,但附有unsafe_unretained 修饰符的变量不属于编译器的内存管理对象。现在可以完全忽略掉这个修饰符了,在iOS4 以后,苹果开始用weak替代了unsafe_unretained。

__autoreleasing 修饰符

__autoreleasing表示在autorelease pool中自动释放对象的引用,和MRC时代autorelease的用法相同。定义property时不能使用这个修饰符,任何一个对象的property都不应该是autorelease型的。

虽然ARC不能直接使用autorelease,但实际上,ARC有效时autorelease功能是其起作用的。

@autoreleasepool { id __autoreleasing obj = [[NSObject alloc] init]; }

指定@autoreleasepool快来代替NSAutoreleasePool类对象生成、持有以及废弃。不需要再手工被创建,也不需要再显式得调用[drain]方法释放内存池.

__autoreleasing在ARC中主要用在参数传递返回值(out-parameters)和引用传递参数(pass-by-reference)的情况下。

ARC有效下的一些规则:

  • 不能使用retain、release、retain、ratainCount、autorelease

  • 不能使用NSAllocateObject/NSDeallocateObject

  • 必须遵守内存管理的方法命名规则

  • 不要显示调用dealloc

  • 使用@autoreleasepool代替NSAutoreleasePool

  • 不能使用区域(NSZone)

  • 对象型变量不能作为C语言结构体的成员

  • 显示转换id和void id型或对象型变量赋值给void 或者逆向赋值都需要进行特定的转换,如果只想单纯的赋值,则可以使用”__bridge 转换“。

属性

ARC有效的时候的属性和所有权修饰符对应的关系:

属性声明的属性

所有权修饰符

assign

_unsafe__unretained修饰符

copy

__strong修饰符(被复制的是被复制的对象)

retain

__strong修饰符

strong

__strong修饰符

_unsafe__unretained

_unsafe__unretained修饰符

weak

__weak修饰符