iPhone程序开发中的内存泄漏问题是新手非常头痛的事情,可能是用C#这类自动垃圾释放的语言太习惯了,用xcode中的profile工具查了一下我写的小程序,内存泄漏了一大堆,经过一阵子排查,在NSMutableArray中添加对象后不正确维护对象的引用计数是一个主要原因。
在NSMutableArrayhow to properly addObjects andrelease这个讨论主题中,给出了正确的使用NSMutableArray的步骤,先看他给出的代码。
NSMutableArray *listData = [[NSMutableArray alloc] init]; for (int i = 0; i < 3; i++) { MyData *obj = [[MyData alloc] init]; NSString *name = nil; switch (i) { case 0: name = @"Semen"; break; case 1: name = @"Ivan"; break; case 2: name = @"Stepan"; break; default: break; } obj.name = name; [listData addObject: obj];
[objrelease];
} [listData release];
里面提到了3个问题,翻译后加上我的理解:
(1)NSMutableArray这个数组里面包含的对象是什么?是对象的一份拷贝,还只是一个对象的指针?
答:数组里存放的不是对象的复本,只是对象的指针。
按以前所学的C++的思维方式,上面的这句[objrelease]是最难理解的,我把obj放在数组里,数组里存放的是对象的引用,为什么把obj释放了?这样数组里存放了一个无效的指针?实际上还是思维方式没有转变过来,在Objective-C中,[objrelease]只表示obj收到一个release消息,如果它的引用计数没有变成0,它就不会释放,而在C++中见到这个release就想到了释放。我们来看一个过程:
MyData *obj = [[MyData alloc]init];
[listData addObject:obj];
[obj release];
[listData release]; //这句会给obj再发一个release消息,这样obj的引用计数变为0,销毁。如果前面那条语句[objrelease]不写,则obj的对象没有正常释放掉,就会造成内存泄漏!
(2)需要先释放掉数组里的所有对象,然后再释放NSMutableArray对象吗?
答:不需要。
在释放NSMutableArray对象里,它自动先给里面的对象发一个release消息。
(3)正确使用NSMutableArray的步骤是什么? (alloc, init, work,release)
答:
1. NSMutableArray *arr =[[NSMutableArray alloc] init];
2. allocobject1.
3. add object1 toarray.
4. releaseobject1.
5. allocobject2.
6. add object2 toarray.
7. releaseobject2.
8. add as many objects as neededin this manner.
8. work withobject1.
9. remove object1 from array. itwill receive a release automatically.
10. [arrrelease];
上述道理对于NSMutableDictionary类的setObject方法也适用。