zoukankan      html  css  js  c++  java
  • OC中的内存管理02

    四、自动释放池 (autorelease)

    1)基本原理:

    1> 自动释放池是OC里面一种内存管理的自动回收机制,一般可以将临时变量添加到自动释放池中,统一回收释放。

    2> 当自动释放池销毁的时候,在自动释放池中所有的对象都会调用一次release方法。

    3> OC对象只要发送一条autorelease消息,会把对象方法放在最近的释放池中(栈顶的释放池)。

    4> autorelease实际上是延迟了release方法的调用,每一次autorelease就会把对象放在当前的autorelease pool中,当pool被释放时,在pool中所有的对象调用该一次release。

    2)自动释放池的创建:

    1> ios 5.0后:

    @autoreleasepool{

    //..........

    }

    2> ios 5.0之前:

    NSAutoreleasePool *pool=

    [[NSAutoreleasePool alloc]init];

    //...............

    [pool release] ;或者 [pool drain];

    3)autorelease的使用:

    1> 以前:

    Book *book = [[BooK alloc] init];

    [Student setBooK:book];

    [book release];

    2> 现在:

    Book *book =[[[Book alloc] init] autorelease];

    [Student setBook:book];

    //不在调用[book release];

    3> 快速创建对象的静态方法:

    + (id) person{

      return [[[Person alloc] init]autorelease];

    }

    外部调用[Person person]时,根本不用考虑什么时候释放返回Person对象。

    4)autoreleasepool的相关疑问:

    疑问:

      在iPhone项目中,main()中有一个默认的Autorelease Pool,程序开始时创建,程序退出时销毁,按照对Autorelease的理解,岂不是Autorelease Pool里的所有对象在程序退出时才release,这样跟内存泄露有什么区别?

    解答:

      对于每一个Runloop, 系统会隐式创建一个Autorelease pool,并且把创建好的pool放在栈顶,所有的pool会构成一个栈式结构。在每一个Runloop结束时,当前栈顶的pool会被销毁,这样这个pool里的每个对象会执行release操作。

    5)autoreleasepool的使用注意:

    1> 在ARC模式下不能使用[[AutoreleasePool alloc] init] ,而应当使用@autoreleasepool。

    2> 不要把大量的循环操作放在NSAutoreleasePool之间,这样会造成内存的峰值上升。

    3> 对于大内存尽量避免使用这种方法,对于这种延迟释放机制还是少用。

    4> sdk中一般利用静态方法创建并返回的对象一本都已经autorelease的,不在需要release了。

    6)@property的参数

    1> 参数可有可无:

    @property int age;

    @property(nonatomic,retain) NSString * name;

    2> 参数的分类:

    读写属性:readwrite/readonly;

    setter处理:assign/retain/copy;

    原子性:atomic/nonatomic;

    3> 默认参数是atomic

    提供多线程保护,在多线程保护下,原子操作是有必要的,否则可能引起错误的结果。

    加了atomic,setter/getter是一个原子操作,如果有多个线程同时调用setter的话,不会出现某个线程在执行setter的全部语句之前,另一个线程开始执行setter的情况,相当于函数头尾加了锁一样的。

    4> 常用的参数noatomic

    写上之后是说明禁止多线程,保护变量,提高性能。

    atomic是OC使用的一种多线程保护机制,防止写入没有完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iphone这种小型设备上,如果没有使用多线程的通讯编程,那nonatomic是一个非常好的选择。另外不涉及锁操作,所以它执行相对快点。

    5> @property其他参数

    readwrite: 产生settergetter readonly: 只产生简单的getter,没有setter。

    assign: 默认类型,setter方法直接赋值,而不进行retain操作

    retain: setter方法release旧值,再retain新值

    copy: setter方法release旧值,再copy新值

  • 相关阅读:
    Unity3d获取APK签名及公钥的方法
    NGUI屏幕自适应
    转:Firefox中firebug和xpath checker工具的使用
    判断输入的手机号和价格是否合法
    IOS 四种保存数据的方式
    IOS开发控制器之间传值的几种小方法
    AlertView的三种弹窗模式
    多线程之NSThread、NSOperation及GCD
    IOS Key-Value Observing (KVO)
    UILabel的相关属性设置
  • 原文地址:https://www.cnblogs.com/nqs674/p/4781675.html
Copyright © 2011-2022 走看看