您的位置:首页 > 其它

OC中自动释放池原理深入剖析

2016-07-28 17:00 295 查看
一、对象------>release(retain -1)----------->(当retain count=0时)dealloc方法调用-------->销毁

说明:

1、销毁对象时肯定先走release方法,如果之后retain count还大于1,则不会释放如果retain count=0,则自动执行dealloc方法,进行销毁

2、执行alloc 方法和copy方法,retain count才会加1.

3、指针赋值时,retain count 不会+1,要想+1,手动调用retain 

二、当创建一个对象时,有四种方式 alloc,new,copy, mutablecopy,

      用完了以后需要手动调用release才行。那么有没有不需要手 动调用的。答案:autorelease

      在创建对象的时候这样做

      [[[classA alloc] init] autorelease]    这样建立的对象,就具备autorelase能力, 后面就不需要再调用release了。那为什么?

      iphone项目启动后,xcode会帮你建立自动释放池auto release pool  ,这个自动释放池中会建立一个数组,存放那些具备autorelease能力的对象。

      只有当程序退出时或手动调用pool release时,自动释放池会释放其中所有autorlease能力的对象,让retain count全部减1,如果此时还大于1则不会调用alloc释放对象。

 注意事项;

  1、autorelease不便大量使用,因为容易造成内存不足。

  2、[NSString stringwithFormat:@"123"]这样创建的对象是具备autorelease能力的,所以自动释放池释放的时候,会让retain count-1,然后看一下是不是等于0,决定是否调用alloc方法看是否可以回收。

      如果你想让他当全局变量,不想让其回收的话,那么你可以手动调用一下retain,然后最终,你自己决定再release

练习 :

     for (int i = 0 ; i < largeNumber; i++) {

NSString *str = [NSString stringWithFormat:@"hello -%04d",i];
}

这个题,str对象能否释放。

分析:

    以上是一个消息循环, 所以此时会自动创建一个runloop释放池,然后具备autorelease能力的str对象是存到这里的。只有当循环结束的时候,释放池才会释放所有autolease对象。

    所以无法做到循环一次就释放一次。如果让每一次的循环结束时都释放一次内存,怎么做呢?

    答案是:创建局部自动释放池。    

    for (int i = 0 ; i < largeNumber; i++) {

        @autoreleasepool {

            NSString *str = [[NSString alloc]initWithFormat:@"hello -%04d",i];

            

        }

    }

    

  总结:做多线程开发时,需要在线程调度方法中手动添加自动释放池,尤其是当执行循环的时候,如果循环内部有使用类的快速创建方法创建的对象, 一定要将循环体放到自动释放池中。       

        
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: