Почему у моего NSURLResponse утечка памяти при архивации? - PullRequest
0 голосов
/ 01 марта 2010

Я обнаружил утечку в моем коде, когда архивирование и разархивирование 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 Ответ

1 голос
/ 02 марта 2010

Управление памятью в Objective-C так же просто, как если бы вы знали, что каждый раз, когда вы вызываете что-то, у которого есть «alloc», «new» или «copy» в имени метода (или если вы сохраняете его), вы должны освободить это в какой-то момент. См. Это для получения дополнительной информации: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

В вашем случае кажется, что вы вызываете alloc для создания NSMutableData, но никогда не освобождаете его (поэтому [saveData release] в конце doStuffWithResponse: может устранить хотя бы одну утечку). Из этого кода это также относится к вашему выделенному NSKeyedUnarchiver и выделенному NSURLResponse.

Если вы не удерживаете значение, как в ivar, вы также можете просто вызвать autorelease сразу после alloc'ing или использовать создателей класса, которые автоматически освобождены, если они доступны (например, [NSString stringWithFormat:] вместо [[NSString alloc] initWithFormat:]).

Выбор Build> Build and Analyze также может выявить такие проблемы.

...