0

苹果操作系统 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]
目标不响应此消息选择器。

4

2 回答 2

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]; 

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

于 2010-04-29T20:59:00.897 回答
0

你什么时候检查内存使用情况?是在您发布的代码片段之后吗?archivePath并且lingeringDataContainer都是自动发布的。直到(至少)自动释放池被耗尽(通常在当前事件结束时)它们才会被释放。可能还有很多其他内部的东西已经被自动释放并且在池被耗尽之前不会消失。

尝试这样做:

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];
于 2010-04-30T15:11:22.353 回答