singleton

bofybofy Membre
13:27 modifié dans API AppKit #1
Bonjour

J'ai découvert les singleton et je suis en train d'apprendre à  m'en servir.
Exemple :
<br />	//--------<br />	CreateMenu * createMenu = [[CreateMenu alloc] init];<br />	[createMenu createMenu];<br />	NSLog(@&quot;createMenu : %@&quot;, createMenu);<br />	//--------<br />	CreateMenu * createMenu1 = [[CreateMenu alloc] init];<br />	[createMenu1 createMenu];<br />	NSLog(@&quot;createMenu1 : %@&quot;, createMenu1);<br />

J'ai inséré dans la classe CreateMenu ce qu'il faut pour en faire un singleton, selon la doc apple.
Ca marche partiellement : le deuxième NSLog me donne nil : c'est déjà  un progrès.
Mais j'attendais de voir la même adresse que la première instanciation de CreateMenu.
Est-ce possible ? si oui où est l'erreur ?

Merci

Réponses

  • schlumschlum Membre
    13:27 modifié #2
    Es-tu sûr que tu as compris le principe de singleton ?

    Normalement la récupération est une méthode de classe, pas d'instance  ;)

    [CreateMenu createMenu];

    C'est tout...
  • bofybofy Membre
    13:27 modifié #3
    dans 1220274272:

    Es-tu sûr que tu as compris le principe de singleton ?

    Bien sûr que non ...
    dans 1220274272:
    Normalement la récupération est une méthode de classe, pas d'instance  ;)
    [CreateMenu createMenu];
    C'est tout...


    Bon j'ai changé ma méthode d'instance en méthode de classe, et ça marche.

    Le peu que j'ai compris : quand on instancie une classe singleton, il n'y a qu'une instance, toujours la même, à  chaque instanciation.

    Cette instance a une adresse, unique je pense. Comment accéder à  cette adresse ?
    Ca me permettrait de vérifier que mon code est (à  peu près) correct ?

    Merci


  • NoNo Membre
    septembre 2008 modifié #4
    dans 1220278899:

    Le peu que j'ai compris : quand on instancie une classe singleton, il n'y a qu'une instance, toujours la même, à  chaque instanciation.

    Oui, c'est ça.
    Normalement, le premier alloc/init créé et retourne le premier objet de la classe singleton.
    Les alloc/init suivants ne doivent pas créer d'autres nouveaux objets, mais retourner celui créé en premier.
    Souvent, il existe comme Schlum le dit une méthode de classe spécifique qui retourne aussi cet objet créée en premier : souvent c'est sharedInstance, ou alors defaultInstance, mais il n'y a rien d'officiel.

    dans 1220278899:

    Cette instance a une adresse, unique je pense. Comment accéder à  cette adresse ?

    L'adresse de ce premier objet créé doit être stockée dans une "pseudo" variable de classe.
    Souvent, il s'agit d'ajouter dans le fichier d'implémentation (en haut après les #import par exemple) une variable de style :
    static id *objetSingleton=nil;.
    Ensuite, tu peux lire ou modifier cette variable objetSingleton depuis n'importe quelle autre méthode de ta classe.
    Cette variable est unique, quelque soit l'objet de ta classe.
    Donc lors du premier alloc/init, tu enregistres l'adresse de ton premier objet dans cette variable.
    Lors des alloc/init suivants (ou d'appel de la méthode spécifique qui retourne l'objet singleton), il faut retourner le contenu de cette variable.
  • Paisible.frPaisible.fr Membre
    13:27 modifié #5
    Petite digression: connaissez vous un bon tutoriel en ligne sur les design-patterns ?
    Si possible adapté à  Objective-C (on peux toujours réver  :( )
  • bofybofy Membre
    13:27 modifié #6
    dans 1220281160:

    dans 1220278899:

    Le peu que j'ai compris : quand on instancie une classe singleton, il n'y a qu'une instance, toujours la même, à  chaque instanciation.

    Oui, c'est ça.
    Normalement, le premier alloc/init créé et retourne le premier objet de la classe singleton.
    Les alloc/init suivants ne doivent pas créer d'autres nouveaux objets, mais retourner celui créé en premier.
    Souvent, il existe comme Schlum le dit une méthode de classe spécifique qui retourne aussi cet objet créée en premier : souvent c'est sharedInstance, ou alors defaultInstance, mais il n'y a rien d'officiel.

    dans 1220278899:

    Cette instance a une adresse, unique je pense. Comment accéder à  cette adresse ?

    L'adresse de ce premier objet créé doit être stockée dans une "pseudo" variable de classe.
    Souvent, il s'agit d'ajouter dans le fichier d'implémentation (en haut après les #import par exemple) une variable de style :
    static id *objetSingleton=nil;.
    Ensuite, tu peux lire ou modifier cette variable objetSingleton depuis n'importe quelle autre méthode de ta classe.
    Cette variable est unique, quelque soit l'objet de ta classe.
    Donc lors du premier alloc/init, tu enregistres l'adresse de ton premier objet dans cette variable.
    Lors des alloc/init suivants (ou d'appel de la méthode spécifique qui retourne l'objet singleton), il faut retourner le contenu de cette variable.


    Bon, je crois que je commence à  comprendre...
    - première erreur : j'avais placé objetSingleton après @implementation (est-ce bien une erreur ?)
    - deuxième erreur : je n'avais pas compris qu'il fallait placer le code de la méthode principale de la classe dans ce que la doc apple appelle sharedManager, après le "[[self alloc] init]", ce qui est compréhensible après coup, mais aurait mérité  un "// ... your code here"

    En tout cas en faisant deux fois de suite [CreateMenu createMenu]; j'ai bien la même adresse pour objetSingleton !

    Je continue à  explorer les singleton et notamment leur capacité à  remplacer les variables globales du C. Je pense que j'aurais encore des questions à  poser ...

    Merci à  tous
  • NoNo Membre
    septembre 2008 modifié #7
    dans 1220282950:

    Bon, je crois que je commence à  comprendre...
    - première erreur : j'avais placé objetSingleton après @implementation (est-ce bien une erreur ?)

    Ce n'est pas une erreur.
    Le mot clé static va tout simplement transformer la variable en variable globale C (avec toute fois une portée "visible" uniquement dans le source qui contient la déclaration).
    J'ai pour habitude de regrouper les variables de la classe en haut du fichier entre les #import et le @implementation, uniquement pour la lisibilité du machin, mais ce n'est pas une obligation.

    dans 1220282950:

    Je continue à  explorer les singleton et notamment leur capacité à  remplacer les variables globales du C. Je pense que j'aurais encore des questions à  poser ...

    Ben, Obj-C ne connait pas les vrais variables de classe (au sens C++ ou java du terme).
    Donc on les simule via des variables globales C.

    Il y a un topic qui parle des variables de classe : c'est par ici.
  • schlumschlum Membre
    13:27 modifié #8
    dans 1220282573:

    Petite digression: connaissez vous un bon tutoriel en ligne sur les design-patterns ?
    Si possible adapté à  Objective-C (on peux toujours réver  :( )


    Il y a une infinité de design-patterns...

    Les plus utilisés :
    http://fr.wikipedia.org/wiki/Patron_de_conception
  • bofybofy Membre
    13:27 modifié #9
    Bonjour

    Je sais maintenant créer un singleton (plus ou moins correctement !).

    Quelle est la façon cocoa correcte de récupérer des variables définies dans la méthode de classe du singleton ?

    J'ai utilisé plusieurs configurations (qui marchent), mais qui ne me satisfont pas.

    Merci
  • NoNo Membre
    13:27 modifié #10
    dans 1220444549:

    Quelle est la façon cocoa correcte de récupérer des variables définies dans la méthode de classe du singleton ?
    J'ai utilisé plusieurs configurations (qui marchent), mais qui ne me satisfont pas.

    Qu'entends tu par "récupérer des variables définies dans la méthode de classe du singleton" ?
    Car une variable définie dans une méthode n'est à  priori pas récupérable.

    Et qu'est cette "méthode de classe" ? Il peut y en avoir plusieurs, la plus connue étant alloc...

    Veux-tu parler de tes variables d'instance (celles dans le @interface), ou des variables de la classe (celle définies en static) ?
  • bofybofy Membre
    13:27 modifié #11
    dans 1220449555:

    Veux-tu parler de tes variables d'instance (celles dans le @interface), ou des variables de la classe (celle définies en static) ?


    Bon, mon problème est de récupérer les "variables de la classe (donc celles définies en static)".
    Faut-il implanter des sortes de getter ?
    Les property ne semblent marcher que pour les variables d'instance ...
  • NoNo Membre
    13:27 modifié #12
    dans 1220454311:

    dans 1220449555:

    Veux-tu parler de tes variables d'instance (celles dans le @interface), ou des variables de la classe (celle définies en static) ?

    Bon, mon problème est de récupérer les "variables de la classe (donc celles définies en static)".
    Faut-il implanter des sortes de getter ?
    Les property ne semblent marcher que pour les variables d'instance ...

    Généralement, les variables de la classe ne sont utilisées que par cette même classe.
    Donc, inutile de faire un getter spécifique :
    <br />#import &quot;UneClasse.h&quot;<br />static id __objetSingleton=nil;<br />@implementation UneClasse<br />- (void)uneMethode<br />{<br />&nbsp; &nbsp; NSLog(@&quot;la valeur de ma variable de classe est %x&quot;, __objetSingleton);<br />}<br />@end<br />
    


    Si tu as besoin d'un accès spécifique à  cette variable en dehors de sa classe, alors tu peux effectivement faire un getter (en méthode de classe) :
    <br />#import &quot;UneClasse.h&quot;<br />static id __objetSingleton=nil;<br />@implementation UneClasse<br />+ (id)objetSingleton<br />{<br />&nbsp; &nbsp; return __objetSingleton;<br />}<br />@end<br />
    

    et :
    <br />NSLog(@&quot;l&#39;objet singleton de la classe UneClasse est : %x&quot;, [UneClasse objetSingleton]);<br />
    

    Cette dernière méthode est exactement ce qu'a évoqué Schlum dans sa première réponse.
  • bofybofy Membre
    13:27 modifié #13
    Merci à  tous

    Au cours de cette discussion, plein de choses se sont précisées. J'ai compris l'utilité de notions dont je ne comprenais pas vraiment l'utilité, bien au delà  de la notion de singleton qui, au demeurant, me parait fondamentale et nécessaire.

    En principe, vous n'entendrez plus parler de moi de longtemps, pendant que je réorganise mon code...
Connectez-vous ou Inscrivez-vous pour répondre.