• 内存管理


    一 关于set函数

    - void setA: (A*) pa

    {

    //pa 有了新的所有者 所以要先 增加引用计数

    [pa retain];

    //该类中的数据成员a 原先所指的内存要释放 否则 会内存泄露

    [a release];

    //最后才能将 a 赋值成 pa

    a = pa;

    }

    二 原则

    1. 谁产生的内存,谁负责释放。(产生的内存是指通过 alloc new copy创建的实例)不是你产生的内存,不需要调用 release.

    2 是1的一种特例。在函数内部 调用 alloc new copy 产生一个实例,并且返回这个实例,也就是作为返回值。依然遵循谁产生,谁负责。只是在return的时候 需要使用 autorelease。 例如 

    -NSString* desc()

    {

    NSString* description = [[NSString alloc] initWithFormat:@"good %d",5]; 

    return [description autorelease];

    }

    所以在2的这种情况,你调用了是不需要你释放的 原因是你没有使用 alloc new copy 产生这个对象实例。但是,如果你想要长期保存这个数据,那么则需要retain 增加一个引用,因为 autorelease 会自己释放掉的。

    三 关于自动释放内存池

    当某些实例不是使用  alloc, new, copy产生的, 而是 使用 第二节中2情况产生的,那么如果循环产生很多个这样的对象 比如 100000个,就会在没有调用自动释放内存池之前产生大量的内存使用。为了避免这种情况,可以自己创建一个内存池来管理,然后释放。

    代码如下:

    NSAutoreleasePool * pool = [[NSAutoreleasePoolallocinit];

        for (int i = 0; i < 100000; i++)

        {

            id obj = [someobj objectAtIndex:i];

            NSString* desc = [obj desc];

            

            if (i !=0 && i % 128 == 0)

            {

                [pool release];

                

                pool = [[NSAutoreleasePoolallocinit];

            }

        }

     

    这里又有另外一个问题,就是 autorelease的对象 会自己加入我们自己创建的 自动释放池吗? 答案是 :会的。因为 系统会将每一个新创建的 自动释放池 放到一个 栈的顶部,所以当有autorelease的消息产生时,就会放到顶部的 自动释放池。

  • 相关阅读:
    you must restart adb and eclipse的相关解决办法
    配有Tesla K40c的服务器新装Ubuntu16.04并安装CUDA8.0、Anaconda3、Matlab2016a、OPENCV3.1、CuDNN5.1、MXNet
    MXNet在64位Win7下的编译安装
    [Kinect]XBox One Kinect连接Windows
    64位Win7下编译Python3的计算机视觉库:OpenCV
    64位Win7下安装并配置Python3的深度学习库:Theano
    Noah的学习笔记之Python篇:命令行解析
    Noah的学习笔记之Python篇:函数“可变长参数”
    Noah的学习笔记之Python篇:装饰器
    linux下安装MySQL5.6记录
  • 原文地址:https://www.cnblogs.com/careerman/p/2646784.html
Copyright © 2020-2023  润新知