Un comportamiento inesperado de la clase Singleton en iPhone, ¿estoy haciendo algo mal?

StackOverflow https://stackoverflow.com/questions/1002364

  •  05-07-2019
  •  | 
  •  

Pregunta

Estoy implementando una clase singleton de la siguiente manera:

static Singleton* _singletonInstance;

@implementation Singleton

+(void)initialize
{ 
    _singletonInstance = [[Singleton alloc] init]; 
}

+(Singleton*)instance
{
    return(_singletonInstance);
}

inicializar solo se llama la primera vez que alguien llama instancia. Luego tengo un método al que puedo llamar para configurar algunas variables de instancia. Así que termina pareciéndose a esto.

_singleton = [Singleton instance];
[_singleton setupWithParams: blah];

Cuando obtengo una instancia de este singleton dentro de un objeto, funciona bien la primera vez; Sin embargo, después de repartir y crear una nueva copia del objeto que necesita una instancia del singleton, aparece un error de ACCESO MALO cuando intento llamar a la función de configuración.

Solo para probar cosas, imprimo la dirección de la instancia antes de realizar la llamada de configuración y ambas veces informan de la misma dirección, pero cuando reviso el registro de errores para la llamada BAD ACCESS, enumera una dirección de memoria completamente diferente.

¿Alguien tiene alguna idea de por qué este puntero a la instancia parece estar bien cuando lo imprimo, pero cuando hago una llamada, parece que apunta a datos aleatorios?

¿Fue útil?

Solución

El valor del puntero parece válido porque solía serlo, pero lo más probable es que la memoria haya sido liberada, razón por la cual apunta a que parecen datos aleatorios.

Ha adquirido una referencia con su [[Singleton alloc] init] arriba, pero ¿hay una versión de en algún otro lugar que pueda estar ejecutando? Apuesto a que su código está llamando a instance , y luego release -ing más tarde, a pesar de que su código nunca adquirió una referencia. Y eso no debería ser necesario para un singleton de todos modos. Solo una conjetura ...

Otros consejos

¿Estás desasignando tu _singletonInstance en algún lugar?

Estoy usando una versión mucho más compleja, pero muy estable, de la plantilla Singleton (tomada con la descripción 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;
}

El código de Valerii es mejor para implementar un singleton, pero el problema es casi seguro que el código que llama [instancia de Singleton] está operando como si tuviera la propiedad sin tomar posesión de la propiedad y luego se libere.

Busque su error y lea Gestión de la memoria Reglas .

También, en Xcode, active NSZombieEnabled y la consola le mostrará cuándo intente enviar un mensaje al objeto después de que se haya liberado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top