一 关于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 = [[NSAutoreleasePoolalloc] init];
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 = [[NSAutoreleasePoolalloc] init];
}
}
这里又有另外一个问题,就是 autorelease的对象 会自己加入我们自己创建的 自动释放池吗? 答案是 :会的。因为 系统会将每一个新创建的 自动释放池 放到一个 栈的顶部,所以当有autorelease的消息产生时,就会放到顶部的 自动释放池。