0

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 を解凍すると、Instruments がリークを報告します。それをコメントアウトして使用しない場合、リークはありません。興味深いのは、代わりに 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 のアーカイブにバグがありますか、それとも何か間違っていますか?

4

1 に答える 1

1

Objective-C でのメモリ管理は、メソッド名に「alloc」、「new」、または「copy」を含むものを呼び出すたびに (または保持する場合)、いつでも解放する必要があることを知っているのと同じくらい簡単です。点。詳細については、http: //developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.htmlを参照してください。

あなたの場合、 alloc を呼び出して NSMutableData を作成するように見えますが、決して解放しないようです (したがって、 doStuffWithResponse: の最後にある [saveData release]: 少なくとも 1 つのリークが解決される可能性があります)。このコードから、これは、割り当てられた NSKeyedUnarchiver と割り当てられた NSURLResponse にも当てはまるようです。

ivar のように値を保持していない場合は、割り当ての直後に autorelease を呼び出すか、利用可能な場合はクラスの自動解放クリエーターを使用することもできます ([[NSString alloc] initWithFormat の代わりに [NSString stringWithFormat:] など)。 :])。

[ビルド] > [ビルドと分析] を選択すると、このような問題が明らかになる場合もあります。

于 2010-03-01T23:32:57.567 に答える