• OC 内存管理



      (一)内存管理方式
    1 Crash(闪退)   90%的原因是因为内存问题
    2 内存问题体现两个方面 : 内存溢出      野指针异常
    2.1 iOS给每个应用程序分配了一定的内存,用于程序的运行,一旦超出内存上限,程序就会Crash
    ****** iPhone3GS内存30M左右,iPhone5s内存80M左右,iPhone6之后是100M左右
    ********3.5寸非Retina屏幕(320*480),
               一张全屏图,占用字节数 329*480*4
                 一个像素占4个字节,存放RGBA,既 600 Bytes
                iPhone 3GS同时读取60张图片就会Crash


    *********4寸屏幕(320*568)实际像素 640 * 11136
            一张全屏图,占用字节数 640 * 1136 *4既2.77 Mbytes
            iPhone 5s 同时读取40张图片就会Crash

    ********* 4.7寸屏幕(375*667)实际像素750*1334
         一张全屏图片,占用字节数750*1334*4 既3.82M Bytes
         iPhone 6 同时读取27张图片就会Crash

    *********  5.5屏幕(414*736),实际像素1080*1920
         程序存放全屏图,占用字节数1080*1920*4,既7.91M bytes
         iphone 6 同时读取131张图片就会Crash
        
    ********* iOS6之后,系统分给每一个APP的大小是100M左右,运行期间使用内存超过这个上限,立即Crash

    2.2 野指针:对象的内存已经被系统回收,但是仍然使用指针操作这块内存。
          代码量越大,程序越容易出现野指针问题
    *****访问没有所有权的内存,如果想要安全的访问,必须确保空间还在
    2.3 过度释放 :在同一块引用计数为1的内存释放多次。立即Crash
    2.4 内存泄露 :空间使用完之后没有及时的返回系统

    3 垃圾回收机制(Garbage - Collection)
         MRC(Manual Reference Counting)
         ARC(Auto Reference Counting)
    垃圾回收机制:程序员只需要开辟内存空间,不需要 代码的 形式释放,系统来判断哪些空间不再被使 ,并回收这些内存 空间,以便再次分配。整个回收的过程不需要写任何代码,由 系统 动完成垃圾回收。Java开发中一直使用的就是垃圾回收 技术。

         MRC(Manual Reference Counting)
    人工引用计数:内存的开辟和释放 都由程序代码进 控制。相对垃圾回收来说,对内存的控制更 加灵活,可以在需要释放的时候及时释放,对程序员的要求较 高,程序员要熟悉内存管理的机制
         ARC(Auto Reference Counting)
    自动引用计数:iOS 5.0的编译器特性,它允许用户只开辟空间,不用去释放空间。它不是垃圾回收!它的本质还是MRC,只是编译器帮程序员默认加le释放的代码。

    iOS 支持两种内存管理方式:ARC和MRC
    MRC的内存管理机制是:引用计数
    ARC是基于MRC的

      ******************************************

         内存管理黄金法则:
         如果你对一个对象做了 alloc,copy,retain操作之后,你就有了对象的所有权,你就有责任对它进行release或者autorelease
         简单来说: 只要自己使用了增加引用计数的方法,那就必须使用数量对等的减少方法,如果没有使用,和自己无关,不用处理

         (二)引用计数机制
    **** C语言中,使用malloc 和 free ,进行堆内存的创建和释放
    ****堆内存只有正在使用和销毁两种状态
    ****实际开发中,可能遇到连个以上的指针使用同一块内存
    ****C语言无法记录内存使用者的个数

    1 OC对象的操作       生成对象   持有对象           释放对象                                                销毁对象
    OC中对应的方法        +alloc      -retain            -release/-autorrealease                      -dealloc 
    *********************************************

    让引用计数发生改变的方法:
    1)   +alloc :在堆区开辟内存空间,让被开辟的内存的空间的引用计数从0 变为1
    2)  -retain :将原有对象的引用计数加1
    3)   -copy  : 把某一对象的内容拷贝一份,拷贝出新的对象,会在堆区开辟新的空间,原有对象的引用计数不变,新的对象的引用计数变1
    4)   -release :将原有对象的引用计数立即减1
    5)   -autorrelease 未来的某一时刻引用计数减1
         如果对象之前引用计数为4,autorrelease之后任然为4,未来某个时刻会变为3

    *****************************************************

    2  通过autoreleasepool自动释放池,控制autorelease对象的释放
    向一个对象发送autorelease消息,该对象就会被添加到离 autorelease 最近的自动释放池中,当自动释放池销毁时,为池中的每个对象发送 release 消息
    ****iOS5 之前,使用NSAutoreleasePool 自动释放池类创建对象
         NSAutoreleasePool  *pool = [[NSAutoreleasePool alloc]init];    //自动释放池创建
                     内容
         [pool release]; //自动释放池销毁

    ***********在iOS5之后,不再推荐使用NSAutreleasePool 类,使用 @autoreleasepool{ }替代
         出了大括号,自动释放池才向各个对象发送release消息
         @autoreleasepool{
            自动释放池创建
         }自动释放池销毁

    3   dealloc
    -dealloc 是继承自父类的方法,当对象引用计数为0的时候,由对象自动调用,销毁该对象的空间
    重写dealloc方法,验证对象的空间是否被回收
    -(void)dealloc{
            NSLog(@“%@对象被销毁”,self);
            [super dealloc];//父类对该方法的实现才是真正的回收空间
         }

      (三)内存管理原则
    1 凡是使用了alloc、retain或者copy让内存的引用计数增加了,就需要使用release或者autorelease让内存的引用计数减少。在一段代码内,增加和减少的次数要相等
    2  如果增加的次数大于减少的次数,会造成内存泄露
    3  如果增加次数小于减少的次数,会造成过度释放
    4 如果增肌的次数等于减少的次数,还继续访问,造成野指针问题

        

  • 相关阅读:
    引用赋值的问题
    mysql的笔记
    输入法失败
    eclipse的快捷键
    c++/c在两个文件公用一个变量
    用c++ sttring检测名字是否有空格
    QLineEdit的信号函数
    c++博客转载
    qt-博客
    QT聊天室--重大bug
  • 原文地址:https://www.cnblogs.com/chenbowen/p/6030126.html
Copyright © 2020-2023  润新知