Como liberar uma variável NSMutableDictionary Instância corretamente, com dicionários aninhados, em Objective-C?
-
05-07-2019 - |
Pergunta
Eu tenho uma classe Objective-C que é algo como:
@interface myClass : NSObject
{
NSMutableDictionary *aDict;
}
Seu método setter parece com:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict release];
[newDict retain];
aDict = newDict;
}
Eu criei uma instância do objeto, colocar dados em adict, e agora quer se livrar do objeto, limpando sua memória no processo. Duas perguntas:
1) Devo liberação adict na myClass 's dealloc método, como mostrado?
[aDict release];
=============================================== ==============================
2) Eu tenho aninhados várias crianças dicionários em adict , representado por chaveA e Keyb , assim:
// aDict:
{
keyA = {
keyA1 = "Hello world";
keyA2 = 1234;
};
keyB = {
keyB1 = Earth;
keyB2 = 25000;
};
}
Será que um [liberação adict] mensagem "propagar para baixo da cadeia" e limpeza todas as crianças dicionários dentro de adict, incluindo seus objetos de chave / valor? Ou, eu tenho que fazer alguma coisa para se livrar deles?
Solução
Sim.
objetos Coleção reter as coisas que eles estão coletando, por isso, quando a coleção é desalocado, ele equilibra a manter com autorização.
Então, se um dos dicionários que estava segurando é desalocada, que também irá liberar seus pares de chave / valor, uma vez que o dicionário é um conjunto, e objetos de coleção reter as coisas que eles estão coletando.
O mesmo é válido para matrizes e conjuntos.
No entanto, você tem um bug em seu código. Você tem:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict release];
[newDict retain];
aDict = newDict;
}
Considere o caso quando newDict
é o mesmo objeto como aDict
. Então você liberar o dicionário, é desalocada, e em seguida, tentar retê-lo, mas gritos! É já não existe.
Existem três alternativas para a fixação desta. Aqui estão elas:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict autorelease];
[newDict retain];
aDict = newDict;
}
- (void) setADict: (NSMutableDictionary *) newDict
{
if (aDict != newDict) {
[aDict release];
[newDict retain];
aDict = newDict;
}
}
- (void) setADict: (NSMutableDictionary *) newDict
{
[newDict retain];
[aDict release];
aDict = newDict;
}
Eu diria que o terceiro é mais simples, o segundo é mais rápido ao longo do tempo, eo primeiro é meh . O primeiro vai bagunçar suas piscinas disparo automático (que pode ou não levar ao inchaço de memória). O segundo eo terceiro são equivalentes em termos de gestão da segurança e propriedade de memória. No entanto, o segundo vai poupar chamadas de método desnecessários se acontecer de você estar definindo o mesmo dicionário sobre si mesmo.
Outras dicas
NSMutableDictionary
vai liberar todos os objetos (valores) na liberação.
NSMutableDictionary
cópias chave e enviar reter a valor para cada par chave / valor que você adicionou. prática de cacau é que quando algo mantém referência então é responsável por liberá-lo.
referência Veja NSMutableDictionary
Métodos que adicionam entradas para dicionários-se como parte de inicialização (para todos os dicionários) ou durante a modificação (por mutável dicionários) -copy cada argumento chave (Chaves devem estar de acordo com o NSCopying protocolo) e adicionar os exemplares para o dicionário. Cada valor corresponde objeto recebe uma mensagem a reter garantir que ele não será desalocada antes de o dicionário é completamente com -lo.