内存管理

一 关于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的消息产生时,就会放到顶部的 自动释放池。

原文地址:https://www.cnblogs.com/careerman/p/2646784.html