Um comportamento inesperado classe Singleton no iPhone, estou fazendo algo errado?
-
05-07-2019 - |
Pergunta
Estou implementando uma classe singleton da seguinte forma:
static Singleton* _singletonInstance;
@implementation Singleton
+(void)initialize
{
_singletonInstance = [[Singleton alloc] init];
}
+(Singleton*)instance
{
return(_singletonInstance);
}
initialize só é chamado pela primeira vez instância alguém chama. Em seguida, tenho um método que eu posso chamar para configurar algumas variáveis ??de instância. Por isso, acaba com essa aparência.
_singleton = [Singleton instance];
[_singleton setupWithParams: blah];
Quando eu recebo uma instância dessa singleton dentro de um objeto, ele funciona bem na primeira vez; No entanto, depois que eu Dealloc e criar uma nova cópia do objeto que precisa de uma instância do singleton, eu recebo um erro de acesso ruim ao tentar chamar a função de configuração.
Só para testar as coisas que eu imprimir o endereço da instância antes de eu fazer a chamada configuração e ambas as vezes eles relatam o mesmo endereço, mas quando eu verificar o log de erro para a chamada ACCESS BAD, ele lista um endereço de memória completamente diferente.
Alguém tem alguma idéia por que isso ponteiro para a instância parece olhar bem quando eu imprimi-lo, mas quando eu faço uma chamada para ele, ele é aparentemente apontando para dados aleatórios?
Solução
O valor do ponteiro parece válido porque ele costumava ser, mas muito provavelmente a memória foi free'd, razão pela qual o que aponta para se parece com dados aleatórios.
Você adquiriu uma referência com o seu [[Singleton alloc] init]
acima, mas existe uma release
em outro lugar que possa estar executando? Aposto que seu código está chamando instance
, e depois release
-ing mais tarde, apesar de seu código nunca adquiriu uma referência. E isso não deve ser necessário para um singleton de qualquer maneira. Apenas um palpite ...
Outras dicas
Você deallocing seu lugar _singletonInstance?
Eu estou usando muito mais complexa, mas a versão muito estável do modelo Singleton (tirada com a descrição de Brandon "Quazie" Kwaselow Blog ):
static SampleSingleton *sharedSampleSingletonDelegate = nil;
+ (SampleSingleton *)sharedInstance {
@synchronized(self) {
if (sharedSampleSingletonDelegate == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedSampleSingletonDelegate;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedSampleSingletonDelegate == nil) {
sharedSampleSingletonDelegate = [super allocWithZone:zone];
// assignment and return on first allocation
return sharedSampleSingletonDelegate;
}
}
// on subsequent allocation attempts return nil
return nil;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX; // denotes an object that cannot be released
}
- (void)release {
//do nothing
}
- (id)autorelease {
return self;
}
código de Valerii é melhor para implementar um singleton, mas o problema é quase certamente que o código que chama [instância Singleton] está operando como se ele tem propriedade sem realmente tomar posse usando reter, e depois mais tarde é liberá-lo.
Olhe lá para o seu erro, e leia a Memória Managment regras .
Além disso, no Xcode, permitir NSZombieEnabled eo console irá mostrar-lhe quando você tentar mensagem o objeto após a sua sido liberado.