自动引用计数


前言

提示:这里可以添加本文要记录的大概内容:

这部分其实之前浅浅提过一点,可以看看这篇博客中的ARC和MRC部分
这篇博客就在学习一下关于这个引用计数部分


自动引用计数

定义

自动引用计数,是指ARC(Automatic Reference Counting),内存管理中对引用采用自动计数的技术。
在Objective-c采用自动引用计数(ARC)机制后,编译器将自动进行内存管理,不需再次retain后release
课降低内存泄漏,程序崩溃的风险,也可以减少代码量。

内存管理方法

引用计数式内存管理原则

  • 自己生成的对象自己持有
  • 非自己生成的对象,也可以持有
  • 不在需要自己持有对象时释放
  • 非自己持有的对象无法释放

方法对应

操作Objective—C方法
生成并持有对象alloc/new/copy/mutableCopy开头的方法(驼峰命名法)
持有对象retain
释放对象release
废弃对象dealloc

内部实现

系统在运行时维护一张散列表(引用计数表)来管理引用计数,表中key值为内存快地址的散列值,value为该对象的引用计数。
生成对象:在散列表中创建新的一行,记录新对象的引用计数。
持有对象:查找对象的对应行,value值+1
释放对象:查找对象的对应行,如果其值不为1,值-1,如果值为1,销毁对象
在这里插入图片描述

优点

  • 对象用内存块的分布无需考虑内存快头部
  • 引用计数表中各记录中存有内存地址,可以从各个记录追溯到各个对象地址

使用

使用alloc/new/copymutableCopy名称开头的方法名意味着自己生成的对象只有自己持有
allocMyObject/newThatObject/copyThis/mutableCopyYourObject
也意味着自己生成并持有对象

自己生成的对象自己持有


    //自己生成并持有对象
    
    id obj1 = [[NSObject alloc] init];
    id obj2 = [NSObject new];
    
  • copy方法由各类实现的copyWithZone:方法生成并持有对象的副本。
  • 与copy方法类似,mutableCopy:方法由各类实现的mutableCopyWithZone:方法生成并持有对象的副本。
  • copy方法生成不可变的副本,而mutableCopy方法生成可变的副本。

对于allocate/newer/copying/mutableCopying等方法生成的对象并不属于自己生成对象自己持有这一类别。

非自己生成的对象自己持有

使用上述方法之外的方法生成的对象因为非自己生成并持有,自己不是盖对象的持有者


    //非自己生成且自己不持有的对象
    
    id obj1 = [NSMutableArray array];
    
    //自己持有对象
    
    [obj1 retain];
    
    

在上述代码中,NSMutableArray类对象呗赋值给obj1变量,但obj1i自己并不持有对象。我们就使用retain方法来持有对象。
通过retain方法,非自己生成的对象和alloc/new/copy/mutableCopy方法生成的对象一样,变成了自己持有的对象。

不需要自己持有对象时释放

自己生成的对象,一旦不再需要,持有者有义务释放该对象,释放使用release方法。对象一经释放绝不可继续访问。


    //自己生成并持有对象
    
    id obj1 = [[NSObject alloc] init];
    id obj2 = [NSObject new];
    
    //释放对象
    
    [obj1 dealloc];

上边的代码中通过release方法释放了自己生成并持有的对象。
非自己生成并持有的对象,通过retain变为自己持有之后,也可以通过release方法释放。


    //非自己生成且自己不持有的对象
    
    id obj1 = [NSMutableArray array];
    
    //自己持有对象
    
    [obj1 retain];
    
    //释放对象
    
    [obj1 release];
    

使用alloc/new/copy/mutableCopy方法生成并持有的对象和非自己持有但使用retain来持有的对象一旦不再需要,必须使用release方法进行释放

将对象返回给方法的调用方

- (id) allocObject{
	//自己生成并持有对象
	
	id obj = [[NSObject alloc] init];

	return obj;
}

int main {
	//非自己生成并持有的对象
	
	id obj1 = [obj allocObject];
}

autorelease方法:可以使取得的对象存在,但自己不拥有该对象。
使对象能够在超出自己使用范围时能自动并正确释放

在这里插入图片描述

- (id) object{
	id obj = [[NSObject alloc] init];
	//自己持有对象
	
	[obj autorelease];
	//取得的对象存在,但自己不持有对象

	return obj;
}

无法释放非自己持有的对象

对于使用alloc/new/copy/mutableCopy方法生成并持有的对象,或用retain方法持有的对象,持有者是自己,所以在不需要盖对象时将其释放,而由此意外得到的对象绝不能释放


    //自己生成并持有对象
    
    id obj1 = [[NSObject alloc] init];
    id obj2 = [NSObject new];
    
    //释放对象
    
    [obj1 release];

	//对象已经释放
	
	[obj1 release];

由于对象已经释放过一次,在次释放时会导致程序崩溃。
再度废弃已经废弃的对象时崩溃。
访问已经崩溃的对象时崩溃


    //非自己生成且自己不持有的对象
    
    id obj1 = [NSMutableArray array];
    
    //自己持有对象
    
    [obj1 release];
    
    

释放了非自己持有的对象,程序崩溃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山河丘壑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值