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?

Foi útil?

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.

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