ARC(二) ARC规则

7 篇文章 0 订阅

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];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值