理解 ARC

ARC 强制实施新的规则

ARC 强制启用了新的规则。这些新规则旨在提供一个完全可靠的内存管理模型;在某些情况下,它们只是执行最优做法,而在其他情况下他们能够简化你的代码或者显式的推断出你没有处理内存管理。如果你违反了这些规则,你会立即得到一个编译期的错误,而不是一个在运行时变得明显的隐藏 bug。

  • 你不能直接调用 dealloc,或者实现或调用 retainreleaseretainCount,或 autorelease。这些明确禁止不能使用的关键字也包括 @selector(retain)@selector(release),等等。

    你可能会实现一个 dealloc 方法,如果你需要管理除了释放实例变量之外的其他资源。你不必(你确实不能)显式地释放实例变量除非不是通过 ARC 编译的代码,但你需要在系统的类里调用 [systemClassInstance setDelegate:nil]

    在 ARC 下自定义 dealloc 方法不需要调用 [super dealloc](实际上它会导致编译错误)。dealloc 父类的调用是由编译器自动执行的。

    你仍然能够使用 CFRetainCFRelease,和其他相关的 Core Foundation 对象的函数。(请看 Managing Toll-Free Bridging。)

  • 你不能使用 NSAllocateObject 或者 NSDeallocateObject

    你通过 alloc 创建的对象;运行时会负责对象的 dealloc。

  • 你不能在 C 结构体中使用对象对象指针。

    不要使用结构体,而是创建一个 Objective-C 类来管理数据。

  • id 和 void * 之间没有临时转换。
    你必须使用特殊的转换来告诉编译器关于对象的生命周期。你需要做这样的转换,在 Objective-C 对象和 Core Foundation 类型之间使用函数参数来传递。了解更多详情,请看 Managing Toll-Free Bridging

  • 你不能使用 NSAutoreleasePool 对象。 ARC 提供了 autoreleasepool blocks 来替代。这比使用 NSAutoreleasePool 更高效。

  • 你不能使用内存区域的方法。
    再也没有必要使用 NSZone 了,总之它们在运行时被现代 Objective-C 所忽略了。

要让手动的 retain-release 代码交互,ARC 规定了方法命名上的约束:

  • 你不能给访问器取一个 new 开头的名字。例如,申明一个 new 开头的属性除非你指定了一个不同的 getter 方法:
// Won't work:
@property NSString *newTitle;

// Works:
@property (getter=theNewTitle) NSString *newTitle;