黑马程序员--OC内存管理机制(上)

----------------------ASP.Net+Unity开发.Net培训期待与您交流! ----------------------



一、内存管理机制——引用计数

1、什么是内存管理

移动设备的内存极其有限,每个app所能占用的内存是有限制的。当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间。比如回收一些不需要使用的对象、变量等。管理范围:任何继承了NSObject的对象,对其他基本数据类型(int、char、float、double、struct、enum等)无效

   2、引用计数:引用计数的数值表示有几个其它对象在使用它。

每一个对象都拥有一个引用计数:

   当对象被创建的时候,引用计数的值为1

当给对象发送retainCount消息获得当前的引用计数器值

   当发送retain消息的时候,该对象的引用计数加1,该对象的引用计数为2(retain方法返回对象本身)

   当这个对象发送release消息的时候,该对象的引用计数减1

   当一个对象的引用计数为0时,系统自动调用dealloc方法,销毁该对象。

  1. Dog *dog = [[Dog alloc]init];//此时引用计数为1  
  2. NSLog(@"  %d",[dog retainCount]);  
  3.   
  4. [dog retain];//引用计数变成2 
  5.   
  6. [dog release];//引用计数变成1  
  7. [dog release];//引用计数变成0,系统会自动调用dealloc方法,销毁对象,回收内存  

引用计数是实例对象的内存回收唯一参考

3、引用计数(retainCount)是Objective-C管理对象引用的唯一依据。调用实例的release方法后,此属性减一,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们不能手动调用对象的dealloc方法。对于dealloc方法

  它的作用是,当对象的引用计数为0时,系统会自动调用dealloc方法,回收内存,它的一般写法为:

-(void)dealloc                                            -(void)dealloc

{                                                                   {

 [super  dealloc];                                            [personrelease];

}                                                                         [super dealloc];

                                                                    }

对象的销毁应该注意:

  (1)当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收

  (2)当一个对象被销毁时,系统会自动向对象发送一条dealloc消息

  (3)一般会重写dealloc方法,在这里释放相关资源,dealloc就像对象的遗言

  (4)一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用

  (5)不要直接调用dealloc方法

  (6)一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)

4、对象所有权

   当一个所有者(可以是任何一个OC对象)做了以下某个动作的时候,它就拥有了对一个对象的所有权。

 (1)如果创建或者复制某个对象时,则拥有了该对象的所有权,即包含下列关键词时:alloc,allocWithZone:,copy,copyWithZone:,mutableCopy,mutableCopyWithZone:

 (2)如果没有创建或复制对象,而是保留引用,同样拥有该对象的使用权retain

 (3)当拥有了某个对象的所有权,在不需要某一个对象时,需要释放他们,用release,autoRelease

5、引用计数器的作用

 (1)当使用alloc、new或者copy创建一个新对象时,新对象的引用计数器默认就是1

 (2)当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收。换句话说,如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收,除非整个程序已经退出

6、set方法的内存管理

    如果你有个OC对象类型的成员变量,就必须管理这个成员变量的内存。比如有个Book *_book

set方法的实现:

- (void)setBook:(Book *)book{

    if(book != _book) {

       [_bookrelease];

       _book= [book retain];

    }

}

dealloc方法的实现:

- (void)dealloc {

    [_bookrelease];

    [superdealloc];

}

二、自动释放池的相关用法

     1、自动释放池(Autorelease pool),是能够自动释放赤忠的对象的。NSObject类提供了一个autorelease消息,当我们想一个对象发送autorelease消息的时候,这个对象就会随着释放池的销毁而释放。如果要向使用使用自动释放池释放对象,我们首先要有一个入池操作:

  1. //创建自动释放池  
  2. @autoreleasepool {  
  3.           
  4.     //入池对象5.0之后的写法  
  5.           
  6.     }  
  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];  
  2.   
  3.    //入池对象5.0之前写法  
  4.   
  5. [pool release];  

    自动释放池是以栈的形式实现的,当某个对象调用了autorelease方法时,该对象会被加入自动释放池的栈顶。对于发送了autorelease消息的对象,当自动释放池销毁时,自动释放池会对这些对象发送一条release消息,来释放他们。

2、autorelease

  (1)给某个对象发送一条autorelease消息时,就会将这个对象加到一个自动释放池中

 (2)当自动释放池销毁时,会给池子里面的所有对象发送一条release消息

 (3)调用autorelease方法时并不会改变对象的计数器,并且会返回对象本身

 (4)autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了当前的autorelease pool中,当该pool被释放时,该pool中的所有对象会被调用Release

3、向自动释放池发送release及drain消息的区别

       当我们向自动释放池pool发送release消息时,它会向池中的每一个发送了autorelease消息的对象发送一条release消息,并且自身也会销毁。当向它发送drain消息时,只会释放里面吧的对象,而不会销毁自己。




----------------------ASP.Net+Unity开发.Net培训期待与您交流! ----------------------

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值