ARC(一) 所有权修饰符

7 篇文章 0 订阅

ARC是iOS5引入的内存管理功能。

ARC的作用就是,在不需要手动输入retain/release的情况下,自动实现这样的功能:保证对象在生命周期内可以正常存在,在生命周期结束后就被释放。(个人理解,如有错误,欢迎指正)

直接在targets->build phases中修改compiler Flags,是否支持arc。添加:-fobjc-arc,就可以让旧项目支持arc。如果想让原来支持arc的不使用arc则添加-fno-objc-arc

这里写图片描述

所有权修饰符

ARC有效时,id类型和任何对象类型(对象类型就是指向NSObject这样的Objective-C类的指针)都必须附加所有权修饰符,所有权修饰符一共有四种:

_strong修饰符;
_weak修饰符;
_unsafe_unretained修饰符;
_autoreleasing修饰符;

_strong修饰符:

默认情况下,使用的是_strong修饰符。
它表示的是对对象的“强引用”。而一个对象,只要还有变量对它持有强引用,那么这个对象就不会被废弃。

_weak修饰符:
只使用_strong修饰符,有可能产生“循环引用”的问题。

当两个不同的对象各有一个强引用指向对方,那么循环引用便产生了。试想下,一个 book 对象持有多个 page 对象,每个 page 对象又多个属性指向它所属的 book 对象。当你释放了持有 book 和 page 对象的变量时,他们仍然还有强引用指向各自,因此你无法释放他们的内存,即使已经没有变量持有他们。

循环引用容易发生内存泄漏,内存泄漏是指应当废弃的对象在超出其生存周期之后继续存在。循环引用对 app 有潜在的危害,会使内存消耗过高,性能变差和 app 闪退等。

所以有必要使用_weak修饰符,来避免循环引用。

_weak修饰符与strong修饰符相反,提供弱引用。弱引用不能持有对象实例。

_weak修饰符还有一个优点:在持有某对象的弱引用时,如果该对象对释放,那么该弱引用将被赋值nil,这样可以避免野指针(野指针就是指向不可用区域的指针,它不是NULL指针,而是指向“垃圾”内存的指针。产生的原因:1,指针变量没有初始化;2,指针被释放之后,没有被设置为NULL,让人误以为是个合法的指针)。

_unsafe_unretained修饰符

_unsafe_unretained修饰符和_weak修饰符作用类似,但是在对象被释放的之后,不会被赋值nil,这样就容易造成悬空指针(一个指针的指向对象已被删除,那么就成了悬空指针),所以很不安全。

在iOS5以上及OS X Lion以上版本的应用程序中,都可以使用_weak修饰符,在之前的版本中只能使用_unsafe_unretained修饰符。能使用_weak修饰符的时候,尽量使用_weak修饰符。

尽管ARC式的内存管理是编译器的工作,但是使用_unsafe_unretained修饰符的变量,不属于编译器的内存管理对象。

_autoreleasing修饰符

在ARC有效时,不能使用NSAutoreleasePool类,也不能直接使用autorelease但是autorelease功能仍然是起作用的。

在ARC无效时:

/*ARC无效*/
NSAutoreleasePool  *pool = [[NSAutoreleasePool alloc] init];
id   obj  = [[NSObject alloc] init];
[obj  autorelease];
[pool  drain];

在ARC有效时,功能相同的代码如下:

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

一般情况下,我们很少看到显式地附加_autoreleasing修饰符,这是因为在以下几种情况下,即使不显式地使用_autoreleasing修饰符,仍然能够用到autoreleasepool :

(1) 使用alloc/new/copy/mutableCopy以外的方法(比如_strong)来获取非自己生成并持有的对象。编译器会检查方法名是否以alloc/new/copy/mutableCopy开始,如果不是,就自动将返回值的对象注册到autoreleasepool 。

(2) 访问附有_weak修饰符的变量。

id _weak obj1 = obj0;
NSLog(@"class = %@",[obj1 class]);

等同于以下代码:

id _weak obj1 = obj0;
id _autoreleasing tmp = obj1;
NSLog(@"class = %@",[tmp class]);

访问附有_weak修饰符的变量时,必须要访问注册到autoreleasepool 的对象。这是因为,_weak修饰符支持有对象的弱引用,那么在访问该对象的时候,它有可能会被释放,所以需要将这个对象注册到autoreleasepool ,从而保证在@autoreleasepool 块结束之前该对象一直存在。

(3) id*
由于_strong修饰符是默认的,所以id obj等同于id _strong obj。但是,id obj,不等同于id _strong *obj,而等同于id _autoreleasing obj。比如,NSError * error等同于NSError * _autoreleasing * error。

另外,显式地指定_autoreleasing修饰符时,对象变量必须是自动变量。自动变量,只在定义它们的时候才创建,在定义它们的函数返回时系统回收变量所占存储空间。一般情况下,不作专门说明的局部变量,均是自动变量。

如果编译器版本为LLVM3.0以上,即使ARC无效,@autoreleasepool块也能够使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值