iOS_使用ARC需要注意的问题
内存管理基本原则
内存管理的依循下面的基本原则
自己生成的对象,那么既是其持有者
不是自己生成的对象,也可成为其持有者(一个对象可以被多个人持有)
如果不想持有对象的时候,必须释放其所有权
不能释放已不再持有所有权的对象
不管ARC有没有效,该原则始终存在。
所有权关键字
从代码上看,有ARC的代码和没有ARC的代码区别就在下面的几个关键字。
类似 NSObject* 的对象类型,或者 id 类型1,当ARC有效的时候,根据具体情况,这些关键字必须要使用2。
__strong
__weak
__unsafe_unretained
__autoreleasing
__strong是默认的修饰符。
__weak修饰了一个自动nil的weak引用。
__unsafe_unretained声明了一个不会自动nil的weak引用。当变量被释放,那么它就变成了一个野指针了。
__autoreleasing 用来修饰一个声明为 (id *) 的函数的参数,当函数返回值时被释放。
接下来,我们结合下面ARC的使用准则,来看看一些使用ARC后的技术细节。
ARC使用准则
为了比秒程序秒退的尴尬,ARC有效时,我们的代码必须遵循下面的准则。
不能使用 retain/release/retainCount/autorelease
不能使用 NSAllocateObject/NSDeallocateObject
不能使用 NSZone
不能明示调用dealloc
内存管理相关的函数必须遵循命名规则
使用@autoreleasepool代替NSAutoreleasePool
Objective-C 对象不能作为C语言结构体(struct/union)的成员
【id】与【void*】之间需要明示cast
建议使用Objective-C的class来管理数据格式,来代替C语言的struct。不能隐式转换 id 和 void *。
让我们一个一个来分析
不能使用 retain/release/retainCount/autorelease
内存管理完全交给编译器去做,所以之前内存相关的函数(retain/release/retainCount/autorelease)不能出现在程序中。Apple的ARC文档中也有下面的说明。
ARC 有效后,不需要再次使用retain 和 release
如果我们在程序中使用这些函数,经得到类似下面的编译错误信息。
error: ARC forbids explicit message send of ’release’
[o release];
^ ~~~~~~~不能使用 NSAllocateObject/NSDeallocateObject
生成并持有一个Objective-C对象的时候,往往像下面一样使用NSObject的alloc接口函数。
id obj = [NSObject alloc];实际上,如果我们看了GNUstep 中关于 alloc 的代码就会明白,实际他是使用 NSAllocateObject 来生成并持有对象实例的。换言之,ARC有效的时候,NSAllocateObject函数的调用也是禁止的。如果使用,也会遇到下面的编译错误。
error: ’NSAllocateObject’ is unavailable:
not available in automatic reference counting mode同样,对象释放时使用的 NSDeallocateObject 函数也不能使用。
不能使用 NSZone
NSZone 是什么?NSZone 是为了防止内存碎片而导入的一项措施。Zone 是内存管理的基本单元,系统中管理复数的Zone。系统根据对象的使用目的,尺寸,分配其所属的Zone区域。以提高对象的访问效率,避免不必要的内存碎片。但是,现在的运行时系统(用编译开关 __OBJC2__ 指定的情况下)是不支持Zone概念的。所以,不管ARC是否有效,都不能使用 NSZone。
不能明示调用dealloc
不管是否使用ARC,当对象被释放的时候,对象的dealloc函数被调用(就像是C++中对象的析构函数)。在该函数中,需要做一些内存释放的动作。比如,当对象中使用了malloc分配的C语言内存空间,那么dealloc中就需要像下面一样处理内存的释放。
相关新闻>>
- 发表评论
-
- 最新评论 更多>>