我在我的代码中发现了一个泄漏,其中归档和取消归档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有错误,还是我做错了什么?
答案 0 :(得分: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:])。
选择构建>构建和分析也可能揭示此类问题。