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新值

  • 相关阅读:
    成功在C#和VB中将shp转换为CAD
    java 提取字符串中的数字
    java 通用文件下载 excel,pdf,word,jpg,exe,rar
    java org 写excel
    java 通用文件下载 excel,pdf,word,jpg
    重建MDB空间网格大小的工具
    redis5.0 Cluster集群搭建
    选中对象【WPF】自定义控件之依赖属性
    成员函数对象类的const和非const成员函数的重载
    设备注册Linux加载DTS设备节点的过程(以高通8974平台为例)
  • 原文地址:https://www.cnblogs.com/nqs674/p/4781675.html
Copyright © 2011-2022 走看看