Comportement inattendu de la classe Singleton sur iPhone, est-ce que je fais quelque chose de mal?

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

  •  05-07-2019
  •  | 
  •  

Question

J'implémente une classe singleton comme suit:

static Singleton* _singletonInstance;

@implementation Singleton

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

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

initialize n'est appelé que la première fois que quelqu'un appelle une instance. J'ai ensuite une méthode que je peux appeler pour configurer certaines variables d'instance. Donc ça finit par ressembler à ça.

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

Lorsque j'obtiens une instance de ce singleton à l'intérieur d'un objet, cela fonctionne correctement la première fois. Cependant, après avoir créé et créé une nouvelle copie de l'objet nécessitant une instance du singleton, j'obtiens une erreur BAD ACCESS lorsque j'essaie d'appeler la fonction de configuration.

Juste pour tester des choses, j’imprime l’adresse de l’instance avant de lancer l’appel de configuration et renvoie à chaque fois la même adresse, mais lorsque je vérifie le journal des erreurs pour l’appel BAD ACCESS, une adresse de mémoire complètement différente est répertoriée.

Quelqu'un a-t-il une idée de la raison pour laquelle ce pointeur sur l'instance semble bien paraître lorsque je l'imprime, mais lorsque je l'appelle, il semble indiquer des données aléatoires?

Était-ce utile?

La solution

La valeur du pointeur semble être valide car elle l’était, mais la mémoire a probablement été libérée. C’est pourquoi il indique des données aléatoires.

Vous avez acquis une référence avec votre [[Singleton alloc] init] ci-dessus, mais existe-t-il une version qui pourrait être en cours d'exécution? Je parie que votre code appelle instance , puis relâche plus tard, même si votre code n'a jamais acquis de référence. Et cela ne devrait pas être nécessaire pour un singleton de toute façon. Juste une supposition ...

Autres conseils

Désactivez-vous votre _singletonInstance quelque part?

J'utilise une version beaucoup plus complexe mais très stable du modèle Singleton (prise avec la description de Brandon" Quazie "(blog Kwaselow ):

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;
}

Le code de Valerii convient mieux à l’implémentation d’un singleton, mais le problème, c’est certainement que le code qui appelle [instance Singleton] fonctionne comme s'il possédait la propriété sans en prendre réellement possession à conserver, puis le relâcher plus tard.

Recherchez votre bogue et lisez le Gestion de la mémoire. Règles .

De même, dans Xcode, activez NSZombieEnabled et la console vous indiquera essayez d'envoyer un message à l'objet après sa libération.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top