• OC 内存管理


    OC 内存管理


    iOS内存管理方式

    • ARC Automatic Reference Counting 自动引用计数
    • MRC Manual Reference Counting 手动引用计数

    更改管理方式
    (图片)

    内存管理的问题

    • 内存泄露:不再需要的对象没有释放。
    • 野指针:正在使用的对象提前释放。

    引用计数

    • 每一个对象上都有一个引用计数器
    • 当对象出生时引用计数器为1
    • 当对象调用retain方法时引用计数器+1
    • 当对象调用release方法时引用计数器-1
    • 当一个对象引用计数为0时,这个对象立即被回收

    僵尸对象(BAD_ACCESS错误)

    什么是僵尸对象???

    • 多度释放的对象

    什么是BAD_ACCESS错误???

    • 访问僵尸对象的成员变量或者向僵尸对象发消息

    如何解决上面的两个问题????

    (一)通过 Zombie
    图片:

    (二)Xcode7集成了BAD_ACCESS捕获功能:Address Sanitizer。
    图片:

    dealloc方法

    • 当对象的retainCount=0时自动调用。
    • dealloc里release成员变量对象。
    • dealloc必须调用父类方法,[super dealloc]必须放在最后。
    • dealloc由系统自动调用,不能手动调用。
    • dealloc的优化 self.xxx= nil;

    内存管理原则

    • 谁申请,谁释放。
    • 申请的方法:alloc new copy mutableCopy retain
    • 释放的方法:release

    Autorelease

    (一)基本用法

    • 会将对象放到一个自动释放池中
    • 当自动释放池被销毁时,会对池子里的所有对象做一次release
    • 会返回对象本身
    • 调用完autorelease方法后,对象的计数器不受影响(销毁时影响)

    (二)好处

    • 不需要再关心对象释放的时间

    (三)使用注意

    • 占用内存较大的对象,不要随便使用autorelease,应该使用release来精确控制
    • 占用内存较小的对象使用autorelease,没有太大的影响

    (四)错误写法

    • 连续调用多次autorelease.()释放池销毁时只会执行一次release)
    • Alloc之后调用了autorelease,之后又调用了release。

    (五)Autorelease注意

    • 系统自带的方法中,如果不包含alloc new copy等,则这些方法返回的对象都是autorelease的,如[NSDate date];
    • 开发中经常会写一些类方法来快速创建一个autorelease对象,创建对象时不要直接使用类名,而是使用self
    + (instancetype)person {
        
        return [[[self alloc] init] autorelease];
    }
    

    自动释放池

    • 在ios程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。
    • 当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中
    • 动释放池的创建方式
    - ios 5.0以前的创建方式  
    

    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    [pool release];//[pool drain]用于mac
    - Ios5.0以后
    @autoreleasepool
    {//开始代表创建自动释放池
    ·······
    }//结束代表销毁自动释放池

    ARC内存管理机制

    (一)ARC的判断准则:

    • 只要没有强指针指向对象,对象就会被释放。

    (二)指针分类:

    • 强指针:默认的情况下,所有的指针都是强指针,关键字__strong
    • 弱指针:_ _weak关键字修饰的指针

    声明一个弱指针如下:
    __weak Person *p;
    ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空操作。
    weak Person *p=[[Person alloc] init];//不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针自动清零。
    ARC中在property处不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc]。
    @property(nonatomic,strong)Dog *dog;// 意味着生成的成员变量_dog是一个强指针,相当于以前的retain。
    如果换成是弱指针,则换成weak,不需要加

    (三)ARC的特点总结:

    • 不允许调用release,retain,retainCount
    • 允许重写dealloc,但是不允许调用[super dealloc]
    • @property的参数:

    Strong:相当于原来的retain(适用于OC对象类型),成员变量是强指针
    Weak:相当于原来的assign,(适用于OC对象类型),成员变量是弱指针
    Assign:适用于非OC对象类型(基础类型)

    MRC环境get方法实现

    //atomic下get方法
    - (Person *)p {
        
        [_p retain];
        [_p autorelease];
        
        return _p;
    }
    
    
    
    //nonatomic下get方法
    - (Person *)p {
        
        return _p;
    }
    

    MRC转ARC:
    图片:

    MRC与ARC混编

    ARC工程中也可以使用MRC的类
    在targets的build phases选项下Compile Sources下选择要不使用arc编译的文件,双击它,输入 -fno-objc-arc 即可

    MRC工程中也可以使用ARC的类
    在targets的build phases选项下Compile Sources下选择要使用arc编译的文件,双击它,输入 -fobjc-arc 即可

  • 相关阅读:
    【第四章:互联寄生 上】静态时序分析圣经翻译计划
    【第三章:标准单元库 下】静态时序分析圣经翻译计划
    【第三章:标准单元库 中】静态时序分析圣经翻译计划
    【第三章:标准单元库 上】静态时序分析圣经翻译计划
    如何学习FPGA
    【第二章 STA概念 下】静态时序分析圣经翻译计划
    校招总结—FPGA从入门到放弃
    【第二章 STA概念 上】静态时序分析圣经翻译计划
    【第一章:绪论】静态时序分析圣经翻译计划
    frida-rpc调用
  • 原文地址:https://www.cnblogs.com/xubaoaichiyu/p/5493236.html
Copyright © 2020-2023  润新知