【OC语言】第六篇·内存管理

来源:互联网 发布:恒生指数期货模拟软件 编辑:程序博客网 时间:2024/05/22 15:37
一、内存管理
    1. 为什么要进行内存管理
      移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多是,系统就会发出内存警告,每个app可以用的内存是被限制的,如果内存超过20M,系统就会对该APP发出Memeory Warning消息。收到此消息需要回收一些不需要继续使用的内存空间。

    2. OC内存管理范围
      管理范围:管理任何继承NSObject的对象,对其它类型基本无效。对象类型是程序运行过程中动态分配的,存储在堆区的内存管理主要是对堆区中的对象的内存管理。
      只有OC对象才需要进行内存管理的本质原因:OC对象存放于堆里面,非OC对象一般放在栈里面(栈内存会被系统自动回收)。

   3. 对象所有权:任何对象可以拥有一个或多个所有者。只要对象拥有一个所有者,它就会继续存在。
       Cocoa所有权策略:任何自己创建的对象都归自己所有,可以使用名字以“alloc” 或 “new”开头或名字中包含“copy” 的方法创建对象,可以使用retain来获取一个对象的所有权。

    4. 引用计数器
       1)每个OC对象都有自己的引用计数器,是一个整数(8字节)表示对象引用的次数,即现在有多少东西在使用这个对象。对象刚被创建是,默认计数器值为1,当计数器的值为0时,则对象销毁。
      2)作用:引用计数器是判断对象要不要回收的依据(存在一种例外:对象值为nil时,引用计数器为0,但不回收空间),就是计数器是否为0。
      3)操作:给对象发消息,进行相应的计数器操作
        retain:使计数器+1,该方法返回对象本身。
        release:使计数器-1
        retainCount:获取对象当前引用计数器的值 %ld %tu(无符号长整型)
      4)对象销毁:当一个对象的引用计数器为0是,那么它就会被销毁,其占用的内存也就会被系统回收。
             当对象销毁时,系统就自动会给对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源。
            一旦重写了dealloc方法,就必须调用[super dealloc] ,并且放在代码块的最后调用
           一旦对象被回收了,那么它的存储空间就不再可用,强制使用会导致程序崩溃(野指针错误)

    5. OC内存管理分类:
         MRC 手动管理  ,ARC 自动引用计数,garbage collection(垃圾回收,iOS不支持)

    6. 内存管理的原则:
      1)原则:
             只要还有人使用某个对象,那么这个对象就应该被回收
             只要你想使用这个对象,那么就应该让这个对象的retain引用计数器+1
             当你不想使用这个对象时,那就就应该让这个对象release(引用计数器-1)
             注意:谁创建谁release,谁retain谁release

    7.内存管理研究的内容:
      1)野指针:定义指针没有进行初始化,指向的内存空间被释放
      2)内存泄漏:Person *p = [Person new];  栈区空间p释放了,但是堆区[Person new]没有被释放,那么堆区空间就被泄漏了
      3)僵尸对象就是:对象的空间已经释放掉了,Xcode默认是不检测僵尸对象。

   8. nil是一个对象的值
       NULL是一个通用指针
       NSNul 是一个对象,他不能使用nil的场合

   9. 单个对象内存管理
      1)泄漏问题:
            创建完成后,使用后没有使用release
            没有遵守内存管理原则
            不当使用nil
      2)避免使用僵尸对象的方法:将对象赋值nil

    10. 多个对象内存管理 
      set方法内存管理
       原则:如果在一个类中,有其它类的对象(关联关系),set方法中书写的时候,要判断是否是同一个对象,如果不是release掉旧值,retain新值。

二、@property
    1. get,set方法实现办法:
       1)@property + 手动实现
       2)@property int age + @synthesize age 
       3)@property int age  +@synthesize age = _age;
       4)增强@property 生成get 和set :@property int age 

    2. 参数 格式:@property (参数1 ,参数2) 数据类型 方法名
        【OC语言】第六篇·内存管理 - 枫叶 - 枫叶的博客

     3. 循环retain解决办法
        1)让某个对象先释放,另外一个对象多释放一次
        2)推荐方法:一端使用assign  一端使用retain

三、@class
    1. #import 作用:把要引用的头文件的内容,拷贝到#import处,如果引用的是#import “Person.h” 那么如果Person.h文件内容发生变化了,此时所有引用该头文件的类,需要重新编译。
    2. @class 作用:可以简单的引用一个类(告诉编译器这是一个类,不会包含其内容)
    3. @class使用格式:@class 类名
         好处:引用头文件内容发生改变,而不需要重新编译
    4. 注意:
       1).h 使用@class xx;   .m 中使用#import "xx.h"
       2)假如A类中#import “B.h” ,B类中#import "A.h" 形成循环引用导致错误。@class可以解决循环引用问题

四、自动释放池
    1. 特殊栈结构
    2. 特点:对象可以加入自动释放池中,自动释放池结束时,会给池中的每一个对象发送一条release消息
    3. 使用:@autoreleasepool {           }    //创建自动释放池
                    [对象 autorelease]           //将对象加入自动释放池中
    4. 好处:不用再关心对象释放的时间
                    不用再关心什么时候调用release
    5. autorelease的使用注意
             占用内存较大的对象不要随便使用autorelease
             占用内存较小的对象使用autorelease,没有太大影响

 
      
0 0
原创粉丝点击