Pergunta

Toda vez que eu chamar esse método minha NSMutableData está vazando e eu não consigo descobrir como ligá-lo. de thedata manter a contagem é elevou por um após o decodificador é alocado e inicializado e não tenho idéia do porquê. Estou preso com um manter a contagem de 2 no final do método e tentar liberá-lo faz com que um app falha.

- (void)readVenueArchiveFile:(NSString *)inFile key:(NSString *)inKey
{
    NSMutableData *theData;
    NSKeyedUnarchiver *decoder;


    theData = [NSData dataWithContentsOfFile:inFile];

    decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];

    venueIOList = [[decoder decodeObjectForKey:inKey] mutableCopy];

    [decoder finishDecoding];

    [decoder release];
}
Foi útil?

Solução

Eu sugerem substituir esta linha:

venueIOList = [[decoder decodeObjectForKey:inKey] mutableCopy];

com:

ListClassName *decodedList = [decoder decodeObjectForKey:inKey];
self.venueIOList = decodedList;

Isso torna o gerenciamento de memória de decodedList clara. É considerada a melhor prática para as variáveis ??de instância atribuir usando um método de acesso (exceto em métodos de inicialização). Em sua implementação atual, se você sempre invocar readVenueArchiveFile: uma segunda vez no mesmo objeto, você vazamento (como você vai se decodedList já tem um valor). Além disso, você pode colocar a lógica cópia em seu método de acesso e esquecê-la, em vez de ter que lembrar mutableCopy cada vez que você atribuir um novo valor (assumindo que há uma boa razão para fazer uma cópia mutável afinal?).

Outras dicas

Redução de memória de pico pegada

Em geral, é considerada a melhor prática para a geração de evitar objetos autoreleased.

[A maior parte deste parágrafo alterado de esta questão .] Uma vez que você normalmente (1) não tem controle direto sobre sua vida, objetos autoreleased pode persistir por um tempo relativamente longo e aumentar desnecessariamente o consumo de memória de sua aplicação. Enquanto na área de trabalho este pode ser de pouca importância, em plataformas mais restrita isso pode ser um problema significativo. Em todas as plataformas, portanto, e especialmente em plataformas mais restrita, sempre que possível você é fortemente desencorajados de usar métodos que levariam a objetos autoreleased e em vez encorajados a usar o / padrão de inicialização alloc.

Eu sugerem substituir o seguinte:

theData = [NSData dataWithContentsOfFile:inFile];

com:

theData = [[NSData alloc] initWithContentsOfFile:inFile];

, em seguida, no final do método add:

[theData release];

Isto significa que theData será desalocadas antes de sair do método. Você deve acabar com:

- (void)readVenueArchiveFile:(NSString *)inFile key:(NSString *)inKey
{
    NSMutableData *theData;
    NSKeyedUnarchiver *decoder;

    theData = [[NSData alloc] initWithContentsOfFile:inFile];
    decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];
    ListClassName *decodedList = [decoder decodeObjectForKey:inKey];
    self.venueIOList = decodedList;
    [decoder finishDecoding];
    [decoder release];
    [theData release];

}

Isso faz com que a semântica de gerenciamento de memória clara, e recupera a memória tão rapidamente quanto possível.

(1) Você pode assumir o controle usando suas próprias piscinas disparo automático local. Para saber mais sobre isso, consulte Gerenciamento de memória da Apple Guia de Programação .

Não se preocupe com reter contagem, se preocupar com o equilíbrio dentro de um método. O que você está fazendo neste método parece correto, assumindo venueIOList é uma variável de instância.

Para expandir a minha resposta um pouco: The Unarchiver pode ser reter seus dados durante a operação de desarquivar, e, em seguida, enviar o -autorelease dados quando ele é feito, em vez de -release. Desde que não é algo você fez, não é algo você tem que se preocupar.

A fonte definitiva para a iluminação de gerenciamento de memória refcount relacionada ainda é, IMO, "Retenção -me, Usa-me, Free me " de Stepwise.

Seu código está correto; não há vazamento de memória.

theData = [NSData dataWithContentsOfFile:inFile];

é equivalente a

theData = [[[NSData alloc] initWithContentsOfFile:inFile] autorelease];

Neste ponto thedata tem uma contagem de referência de 1 (se for inferior, que seria desalocada). A contagem de referência será reduzida automaticamente em algum momento no futuro à beira da piscina disparo automático.

decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];

O objeto decodificador mantém uma referência para thedata que incrementa sua contagem de referência para 2.

Depois do método retorna, a piscina disparo automático diminui este valor para 1. Se você soltar thedata no final deste método, a contagem de referência vai se tornar 0, o objeto será desalocada, e seu aplicativo irá falhar quando você tenta usá-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top