为啥存档时我的 NSURLResponse 会泄漏内存?
Posted
技术标签:
【中文标题】为啥存档时我的 NSURLResponse 会泄漏内存?【英文标题】:Why is my NSURLResponse leaking memory when archived?为什么存档时我的 NSURLResponse 会泄漏内存? 【发布时间】:2010-03-01 20:54:41 【问题描述】:我在我的代码中发现了一个泄漏,其中归档和取消归档 NSURLResponse 会导致泄漏,我不知道为什么。
- (void)doStuffWithResponse:(NSURLResponse *)response
NSMutableData *saveData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:saveData];
[archiver encodeObject:response forKey:@"response"];
// Encode other objects
[archiver finishDecoding];
[archiver release];
// Write data to disk
// release, clean up objects
- (void)retrieveResponseFromPath:(NSString *)path
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:[NSData dataWithContentsOfFile:path]];
NSURLResponse *response = [unarchiver decodeObjectForKey:@"response"];
// The above line leaks!!
// decode other objects
// clean up memory and do other operations
当我取消归档 NSURLResponse 时,仪器会报告泄漏。如果我将其注释掉并且不使用它,则没有泄漏。有趣的是,我保存了 NSURLResponse 的片段,没有泄漏:
// Encode:
[archiver encodeObject:[response URL] forKey:@"URL"];
[archiver encodeObject:[response MIMEType] forKey:@"MIMEType"];
[archiver encodeObject:[NSNumber numberWithLongLong:[response expectedContentLength]] forKey:@"expectedContentLength"];
[archiver encodeObject:[response textEncodingName] forKey:@"textEncodingName"];
// Decode:
NSURL *url = [unarchiver decodeObjectForKey:@"URL"];
NSString *mimeType = [unarchiver decodeObjectForIKey:@"MIMEType"];
NSNumber *expectedContentLength = [unarchiver decodeObjectForKey:@"expectedContentLength"];
NSString *textEncodingName = [unarchiver decodeObjectForKey:@"textEncodingName"];
NSURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:url MIMEType:mimeType expectedContentLength:[expectedContentLength longLongValue] textEncodingName:textEncodingName];
有人知道这是为什么吗?归档 NSURLResponse 是否存在错误或我做错了什么?
【问题讨论】:
【参考方案1】:Objective-C 中的内存管理就像知道任何时候调用方法名称中包含“alloc”、“new”或“copy”的东西(或者如果您保留它),那么您必须释放它在某个时候。有关更多信息,请参阅此内容:http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
在您的情况下,您似乎调用 alloc 来创建 NSMutableData,但从不释放它(因此 doStuffWithResponse: 末尾的 [saveData release] 可能会解决至少一个泄漏)。从这段代码中,您分配的 NSKeyedUnarchiver 和分配的 NSURLResponse 似乎也是如此。
如果您不保留该值,例如在 ivar 中,您也可以在分配后立即调用 autorelease,或者使用类的自动释放创建者(如果可用)(例如 [NSString stringWithFormat:] 而不是 [[NSString alloc] initWithFormat:])。
选择构建 > 构建和分析也可能会显示此类问题。
【讨论】:
该代码实际上在 // release, clean up objects 部分下。我没有提供它来提供更多关注导致泄漏的确切位置,但我想它会引起更多混乱。正如我所说,如果我注释掉特定的代码行,仪器会报告零泄漏——静态分析器也不会抱怨那种简单的泄漏。我正在释放所有我我的问题仍然存在的对象。以上是关于为啥存档时我的 NSURLResponse 会泄漏内存?的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 ggplotly 时我的工具提示的顺序会发生变化?
为啥在 Win32 中使用 `GetAsyncKeyState()` 时我的热键会出错?