简体   繁体   English

为什么我的NSURLResponse存档时会泄漏内存?

[英]Why is my NSURLResponse leaking memory when archived?

I found a leak in my code where archiving and unarchiving an NSURLResponse was causing a leak, and I can't figure out why. 我在我的代码中发现了一个泄漏,在该泄漏中归档和取消归档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
    }

Instruments reports a leak when I unarchive the NSURLResponse. 当我取消存档NSURLResponse时,仪器报告泄漏。 If I comment that out and do not use it, there is no leak. 如果我将其注释掉并且不使用它,则不会泄漏。 What was interesting was instead I saved the pieces of the NSURLResponse there is no leak: 有趣的是,我保存了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];

Anyone know why this is? 有人知道为什么吗? Is there a bug with archiving NSURLResponse or am I doing something wrong? 归档NSURLResponse是否存在错误,或者我做错了什么?

Memory management in Objective-C is as simple as knowing that any time you call something that has "alloc", "new", or "copy" in the method name (or if you retain it), then you must release it at some point. Objective-C中的内存管理非常简单,只要知道每次调用方法名称中具有“ alloc”,“ new”或“ copy”的东西(或保留它),就必须在某个时候释放它。点。 See this for more info: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html 请参阅此以获取更多信息: http : //developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

In your case, it appears that you call alloc to create an NSMutableData, but never release it (So [saveData release] at the end of doStuffWithResponse: may resolve at least one leak). 在您的情况下,您似乎在调用alloc创建一个NSMutableData,但是从不释放它(因此doStuffWithResponse结尾的[saveData release]:可以解决至少一个泄漏)。 From this code, this also appears to be the case with your alloc'ed NSKeyedUnarchiver and your alloc'ed NSURLResponse. 从此代码中,分配的NSKeyedUnarchiver和分配的NSURLResponse似乎也是如此。

If you're not holding onto the value, like in an ivar, you can also just call autorelease right after alloc'ing, or use the class's autoreleased creators if available (eg [NSString stringWithFormat:] instead of [[NSString alloc] initWithFormat:]). 如果您不持有该值,例如在ivar中,也可以在分配后立即调用自动释放,或者使用该类的自动释放的创建者(如果可用)(例如[NSString stringWithFormat:]而不是[[NSString alloc] initWithFormat) :])。

Selecting Build > Build and Analyze may also reveal such issues. 选择构建>构建和分析也可能会发现此类问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM