NSData版本不回收内存

时间:2010-04-29 20:53:56

标签: iphone iphone-sdk-3.2

iPhoneOS 3.2

我使用NSKeyedUnarchiver的unarchiveObjectWithFile:来加载包含单个大型NSData和另一个小得多的对象的自定义对象。我的自定义对象中的dealloc方法被调用,NSData对象被释放,其retainCount == 1就在之前。物理内存不会减少任何数量,更不用说NSData大小的一小部分,并且可靠地生成重复内存警告:我已经测试,直到我实际收到2级警告。 =(

NSString *archivePath = [[[NSBundle mainBundle] pathForResource:@"lingering"]
     ofType:@"data"] retain];
lingeringDataContainer = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];
[archivePath release];
[lingeringDataContainer release];

现在是dealloc ......

- (void) dealloc {
   [releasingObject release];
   [lingeringData release]; 
   [super dealloc];
}

发布前:

(gdb)p(int)[(NSData *)lingeringData retainCount]
$ 1 = 1

后:

(gdb)p(int)[(NSData *)lingeringData retainCount]
Target不响应此消息选择器。

2 个答案:

答案 0 :(得分:1)

首先,您要保留并释放不需要发生这种情况的对象。这是清理过的代码:

NSString *archivePath = [[NSBundle mainBundle] pathForResource:@"lingering"]
     ofType:@"data"]; // Do not retain again.
lingeringDataContainer = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath]; // Do not retain again.
// Do not release, because archivePath is already autoreleaed: [archivePath release];
// Again, this is already autoreleased: [lingeringDataContainer release];

或更简单:

NSString *archivePath = [[NSBundle mainBundle] pathForResource:@"lingering"]
     ofType:@"data"];
lingeringDataContainer = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath]; 

其次,代码的其余部分在哪里?它可能是在其他地方保留或缓存的其他东西。

答案 1 :(得分:0)

您何时检查内存使用情况?它刚刚发布在您发布的代码段之后吗? archivePathlingeringDataContainer都已自动释放。在(至少)自动释放池耗尽之前(通常在当前事件结束时),它们不会被释放。可能还有很多其他内部的东西已经自动释放,并且在游泳池耗尽之前不会消失。

尝试这样做:

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // <==
NSString *archivePath = [[[NSBundle mainBundle] pathForResource:@"lingering"]
 ofType:@"data"] retain];
lingeringDataContainer = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];
[pool release];                                             // <==
[archivePath release];
[lingeringDataContainer release];