OC内存管理

一 基本原理
     Objective-C的内存管理机制与Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍加了一些自动方法.
     1,OC采用了引用计数(retain count)对对象内存进行管理,例如,某个对象alloc了,那么这个对象的引用计数就加1,retain时加1,当对象不需要用时就需要销毁对象,释放内存,需要对象调用release方法,release会让引用计数减1,只有引用计数消失,相当于等于0,对象才会调用dealloc真正销毁这个对象.
     OC的对象在使用完成后不能自动销毁,一定要记得释放内存.
     Class *obj = [[Class alloc]init];//对象obj引用计数加1
     Class *obj2 = obj;//两个对象指向同一块内存
     [obj hello];
     [obj release];//对象被销毁
     [obj2 hello];//错误,obj2指向的内存不存在了
     [obj2 release];//[obj release]之后,obj2是个无效指针,没有内存,不能调用方法.
     注:dealloc是自动调用,一定不能手动调用.指针赋值不会使引用计数加1.
     2,OC中引入了autorelease pool(自动释放对象池),在遵守一些规则的情况下,可以自动释放对象.新生成的对象,只要调用autorelease就行了,无需再调用release.
     autorelease pool需要手动建立,在新建一个项目时,xcode会自动创建一个,NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool  内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象,一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去.
   NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每一个成员.如果此时数组中成员的retain count为1那么release之后,retain count为0,对象正式销毁,如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,对象依然没有被销毁,内存就会泄露,所以一定要注意内存管理规则(见下).
   注:什么情况下创建自动释放对象池?1)在多线程里面要自己创建.2)如果代码里面有大量临时变量时最好创建自动释放对象池.
   for(int i=0;i<100;i++){
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        for(int j=0;j<100000;j++){
           [NSString stringWithFormat:@"123455666"];//产生的对象是autorelease的.
        }
        [pool release];
      }
二、规则
 1 谁创建,谁释放。如果通过alloc、new或copy来创建一个对象,那么你必须调用autorelease或在使用完成时调用release,不是你创建的,就不用你去释放。
   2   除了alloc,new或copy之外的方法创建的对象在内部都被声明了autorelease。如,[UIButton buttonWithType:].
   3   谁retain,谁release,只要你调用了retain,无论这个对象是如何生成的,你都要调用release.
三、范式
 1 创建一个对象
     Class *obj = [[Class alloc] init];
   2 创建一个自动释放对象
     Class *obj = [[[Class alloc] init]autorelease];
  3 指针赋值给另一个指针
   Class *obj2 = obj1;
   [obj2 retain];
   [obj2 release];
  4 在一个函数中创建并返回对象,需要把这个对象设置为autorelease
   - (Class *)fun{
     Class *obj = [[[Class alloc] init] autorelease];
     return obj;
   }
  5 在子类的dealloc方法中调用基类的dealloc方法
   - (void)dealloc{
    ……
  [super dealloc];
   }
  对于属性里的内存机制请参考属性详细说明。

注:不要过度依赖retaincount,有时候内部实现并不像表面那样,计数不会换我们看到的那样,例如

MovieViewController *movie = [[MovieViewController alloc]init];

    NSLog(@"===%d",[movie.view retainCount]);//3

    NSLog(@"===%d",[movie.view retainCount]);//4

    NSLog(@"===%d",[movie.view retainCount]);//5

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值