Aller au contenu

Thread safe singleton / shared instance


Messages recommandés

Bonjour.

Pour les besoin de la cause, j'ai besoin de créer un shared Instance d'une classe que j'initialize au lancement du logiciel.

Il est à noter que les shared instance sont, comme beaucoup de chose, critiques en terme de "sécurité".

Il faut éviter que lors de l'initialisation de la classe, une autre initialisation aie lieu. Nous voulons éviter, d'avoir deux instances distinctes alors qu'elles devraient être shared.

De fait, je me demande si @synchronize() est suffisant pour faire une shared instance thread safe.

Voici le code a évaluer, vos avis m'intéressent.

 

(id)sharedInstance
{
  @synchronized(self)
  {
     if(!_sharedInstance)
        _sharedInstance = [[[self class] alloc] init];
     return _sharedInstance;
  }
}

-(id)init
{
  @synchronized(self)
  {
     if(_sharedInstance)
     {
        [self dealloc];
        self = [_sharedInstance retain];
     }
     else
     {
        self = [super init];
        if(self != nil)
        {

        }
        _sharedInstance = self;
     }
     return self;
  }
}

Lien à poster
Partager sur d’autres sites

Avec l'apparition de la libdispatch, je ne peut que conseiller de te débarrasser des @synchronized. C'est assez lent, et pas terriblement pratique.

 

Pour faire un pattern "singleton" (ce que semble indiquer ton sharedInstance), rien de plus simple avec la libdispatch :

 

+ (instancetype)sharedInstance
{
  static dispatch_once_t onceToken;
  static MyClass *shared;

  dispatch_once(&onceToken, ^{
     shared = [[self alloc] init];
  });

  return shared;
}

 

dispatch_once te garantie que le block passé en paramètre sera exécuté de manière synchrone qu'une et unique fois, même en cas de concurrence de plusieurs thread.

C'est LA bonne manière de faire un singleton.

 

Après je te déconseille fortement de bidouiller avec une shared instance dans le init. Le mieux est de ne pas gérer le cas où l'utilisateur de ta classe se créer directement une instance non partagé (quitte à documenter le fait que le comportement en cas d'alloc / init direct n'est pas définit). C'est pas rare qu'Apple fasse ça aussi dans Cocoa.

 

Sinon : passe à ARC, ça va te changer la vie :)

Lien à poster
Partager sur d’autres sites

Je voulais dire : de "changer la vie" en général, pas que pour l'exemple ici.

 

Quant au code qui vient d'ici oui, mais les technologies évoluent. Si le @synchronized était la bonne façon de faire y'a quelque temps, ça n'est plus le cas : il y a maintenant beaucoup plus simple.

Lien à poster
Partager sur d’autres sites

Heu non, c'est juste une déclaration de variable. Elle s'appelle "shared" (j'aurais pu l'appeler "toto") et elle est du type "MyClass" (c'est juste pour l'exemple, il faut mettre le nom de ta classe à la place).

 

Je ne suis pas certain d'avoir compris la question, j'espère que j'y réponds quand même.

Lien à poster
Partager sur d’autres sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

Chargement
×
×
  • Créer...