• 浅谈自动引用计数——内存管理思考方式


    一、OS X Lion 和iOS 5引入的内存管理新功能——自动引用计数 在复习objective-c的内存管理同时,需要详解这个新功能带来的变化

    1/1 什么时自动引用计数

    自动引用计数(ARC ,automatic reference counting) 是指在内存管理中对引用录取自动计数的技术,让编译器来进行内存管理,默认设置ARC为有效状态的情况下,就可以不必再键入(retain release)

    好处:
    1)降低程序崩溃和内存泄漏的风险(内存泄漏是指:操作系统可提供的所有进程空间,在被某个进程榨干,结果就是程序运行的时间越长,耗费的内存越大,程序容易崩溃,那么这种状况都会在什么情况下发生呢:即程序创建了这么一块内存,但是没有一个指针指向它对它进行操作)

    2)减少了程序开发的工作量

    3)编译器完全清楚的知道那些是需要被释放的对象,哪些对象不再需要使用,这样程序将具有可预测性,运行的效率也会提高

    1/2 那么在ARC出现之前,程序员们都是怎么样手工进行内存管理的呢??

    需要对内存引用进行的操作步骤有: 生成对象-》持有对象-》释放对象-》废弃对象

    那么内存管理的思考方式我们也必须要知道:

    引用计数,不只是在计数而已:

      a、自己生成的对象,自己持有(计数生成的可以是你自己生成的对象,自身持有)

      b、非自己持有的对象,也可以自己持有(计数生成的可以是别人的对象,但是你可以引用,也可以自身持有)

      c、不再需要自己持有的对象就释放(自己生成的对象,自身持有完之后,不想要了,那么你就可以释放)

      d、非自己持有的对象无法释放(毕竟你跟它非亲非故)

    我对内存管理的思考方式的理解是这样的:打个比方,你在商店里买了一个商品,那么你就可以拥有它一阵子,你朋友买了一个物品,你同样可以拥有它一阵子,当你觉得你不喜欢了,你可以选择抛弃这件物品,但是你没法跑去商店里把你不喜欢的商品全部抛弃吧

    1/3 对象操作与oc方法的对应

    生成——alloc/new/copy/mutableCopy

    持有 ——retain

    释放——release

    废弃——dealloc

    根据引用计数式的内存管理思考方式,逐一分析:

    a、自己生成的对象自己持有

    使用(alloc、new、copy、mutableCopy 开头的方法名意味着自己生成的对象自己持有)

    id obj=[[NSObject alloc]init];

    id obj=[NSObject new];

    copy方法是基于NSCopying方法约定

    mutableCopy方法是基于NSMutableCopying方法约定

    两者的区别是copy生成的是不可变对象

    但是,请注意:有些方法即便用了alloc/new/copy/mutableCopy 却并不满足自己生成自己持有这一思考模式,为啥呢?

    因为除了要满足开头,还需要满足驼峰拼写法(newHello)后面紧跟大写字母

    b、非自己生成的,同样可以自己持有

    id obj=[NSArray array];

    id obj =[NSMutableArray array];

    取得了对象存在,但是自己不持有对象 即NSMutableArray类被赋给了对象obj,但是对象obj自己并不持有该对象,从而使用:

    [obj retain]; 从而使自己持有对象(持有不是自己生成的对象是需要条件的)

    c、不再需要自己持有的对象时释放

    1)id obj =[[NSObject alloc]init]

    obj生成并持有对象

    [obj release];obj释放对象

    如此,使用alloc方法由自己生成并持有的对象就通过release释放了。

    2)那么自己生成/非自己生成且非自己持有的对象,如果通过retain使得自己持有的话,同样满足“自己生成自己持有” 同样可以通过release释放

    id obj =[NSMutableArray array];  NSMutableArray :此时非自己生成也非自己持有

    [obj retain];此时非自己生成但是自己持有

    [obj release];此时,非自己生成但是自己持有的对象就会被释放

    所以说:不管是不是自己生成的对象,只要自己持有了,就可以对它进行释放

    被释放的对象将不能够再进行访问

    3)当遇到通过方法生成自己对象,并将其返回给调用方时:

    -(id) allocObject

    id obj =[[NSObect alloc]init]; //自己生成并持有

    return obj;

    id obj1 =[obj0 allocObject];

    同样满足自己生成并持有对象 并且allocObject也满足驼峰拼写

    4)调用[NSMutableArray]不代表自己持有也不代表自己生成,只能算是自己取得对象存在的时候,要怎么实现?因为不能直接使用alloc/copy/mutableCopy/new 所以使用其它没有特殊代表的方法名

    -(id)object

    {

    id obj =[[NSObject alloc]init]; 自己生成并持有

    [obj autorelease]; 取得对象存在,但自己不持有对象?

    return obj;

    }

    使用了autorelease方法,用该方法,可以使得得对象存在,但是自己不持有对象,autorelase提供这样的功能,时对象在超出自己制定的生存范围内能够自动并正确的释放。

    那么同样是释放  autorelease和release 有什么区别??

    release:立即释放

    autorelease:把对象注册到autoreleasepool中去,当pool结束时,自动调用release 

    id obj0=[obj1 object];

    可以取得对象的存在,但是不能持有对象,要知道在pool结束的时候,对象已经被释放掉了

    当然,也可以通过retain来将已经取得的对象存在变成自己持有

    id obj0=[0bj1 object];取得对象存在,但非自己持有

    [obj0 retain]; 取得对象存在并自己持有

    总结:通过retain 可以将非自己生成或者已经取得对象存在的对象变为自己持有

    d、无法释放非自己持有的对象

    当持有者不是自己的时候,我们无法对对象进行释放,一旦释放非自己持有的对象,就会造成程序崩溃

    id obj =[[NSObject aloc]init];自己生成并自己持有

    [obj release] 释放掉的对象,非自己持有也非自己生成

    [obj releaes ]

    程序崩溃,因为此时obj已经是非自己持有的对象了 而且无法访问一个已经被废弃的对象

    以上对这四项的分析,就是“引用计数式内存管理”的思考方式。

  • 相关阅读:
    画出直线,找出直线经过的图像坐标
    MFC 对话框图片上,鼠标拖动画矩形框
    MFC知识点整理
    mfc +opencv 读取图片显示到对话框
    python 获取系统时间,新建时间目录
    在Ubuntu下后台持续运行Python程序
    利用conda安装tensorflow
    整理的最全 python常见面试题(基本必考)
    转:Django框架基础知识(面试题)
    shell 获取变量是什么数据类型
  • 原文地址:https://www.cnblogs.com/CityPe/p/5343768.html
Copyright © 2020-2023  润新知