您的位置:首页 > 移动开发 > IOS开发

ARC(二) ARC规则

2016-07-18 21:00 573 查看
1. 不能使用retain/release/retainCount/autorelease

ARC有效时,内存管理就成了编译器的工作,所以就没有必要使用内存管理的方法(retain/release/retainCount/autorelease)。如果使用了这些代码,就会发生编译错误。

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

在ARC无效时,用于对象生成/持有的方法必须遵守以下的命名规则:

alloc

new

copy

mutableCopy

以上述名称开始的方法在返回对象时,必须返回给调用方所应当持有的对象。在ARC有效时,以上规则同样要遵守,但是还要再加上一个:

init

以init开始的方法,比上面的规则更加严格。该方法必须是实例方法,而且必须返回对象。返回的对象,应为id类型或者该方法声明类的类型,也可以是该类的父类或者子类的类型。

init主要和alloc方法配合使用。

3.不能显式调用dealloc

在ARC有效时,不能显式调用dealloc,不然会引起编译错误。

4.使用@autoreleasepool块代替NSAutoreleasePool

在ARC有效时,不能使用NSAutoreleasePool,不然会引起编译错误。如果想要使用autorelease,只能使用@autoreleasepool块。

5. 不能使用区域(NSZone)

NSZone 是为了防止内存碎片而导入的一项措施。系统根据对象的使用目的、尺寸,分配其所属的Zone区域,以提高对象的访问效率,避免不必要的内存碎片。但是,现在的运行时系统(用编译开关
_OBJC2
_ 指定的情况下)是不支持Zone概念的。所以,不管ARC是否有效,都不能使用 NSZone。

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

在C语言的结构体(struct或者union)成员中,如果存在Objective-C对象型变量,便会引起编译错误。

Struct A{
NSMutableArray *array;
}


原因是:ARC把内存管理的工作分配给了编译器,所以编译器必须要知道并管理对象的生存周期,但是C语言没有办法来管理结构体成员的生存周期。

如果一定要将Objective-C对象型变量加入到结构体成员中,可以将它强制转换成void*,或者是附加_unsafe_unretained修饰符。

Struct A{
NSMutableArray  _unsafe_unretained *array;
}


7.显示转换id和void*

在ARC无效时,可以直接进行强制转换,比如:

id  obj = [[NSObject alloc] init];
void * p = obj;


但是在ARC有效时,这样会产生编译错误。这时,可以使用_bridge、_bridge_retained或者_bridge_transfer来进行转换。

(1)_bridge

如果只是想单纯地赋值,可以使用_bridge来进行转换,例如:

id  obj = [[NSObject alloc] init];
void * p = (_bridge  void*)obj;
id  o = (_bridge  id)p;


但是,这样做的安全性很低,很容易产生悬垂指针,从而导致程序崩溃。

(2)_bridge_retained

_bridge_retained可以使要转换赋值的对象也持有所赋值的对象,类似于ARC无效情况下的retain,例如:

id  obj = [[NSObject alloc] init];
void * p = (_bridge_retained  void*)obj;//此时,变量p和obj都持有该对象


上面的源码,等同于以下源码:

/*ARC无效*/
id  obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain];


(3)_bridge_transfer

_bridge_transfer提供和_bridge_retained相反的动作,转换结束后,转换目标持有该对象,而被转换的变量不再持有该对象,类似于RC无效情况下的release,例如:

id  obj =  (_bridge_transfer  id)p;//此时,id持有该对象,而p不再持有该对象


上面的源码,等同于以下源码:

/*ARC无效*/
id  obj = (id)p;
[obj retain];
[(id)p retain];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内存管理 iOS OC