Utiliser un singleton

PhildesPhildes Membre
21:19 modifié dans API AppKit #1
Bonjour,
mon but est de simuler une variable globale comme on pouvait en utiliser en C.
Pour ce faire j'ai parcouru plusieurs forums qui suggèrent en Cocoa, l'usage d'un singleton.
Trouvant la doc d'Apple un peu difficile à  ingérer pour un débutant, je me suis référé à  quelques messages de ce forum, traitant des singleton. J'ai entre autres téléchargé et installé un programme simulant l'utilisation d'un singleton ici :
http://www.pommedev.com/index.php?action=dlattach;topic=3824.0;attach=2750
Cependant, je ne vois pas la méthode pour passer la valeur d'une variable à  conserver, comme le ferait une variable globale en C.
Merci de vos explications :)

Réponses

  • AliGatorAliGator Membre, Modérateur
    21:19 modifié #2
    En fait un Singleton est une classe qui n'a qu'une instance unique, c'est tout. Une fois que tu as accédé à  cette instance unique, tu l'utilises comme n'importe quelle instance / objet Objective-C.
    // récupérer l&#39;instance unique du singleton sharedInstance, ça retournera donc toujours le même unique objet :<br />MonSingleton* s = [MonSingleton sharedInstance];<br /><br />// ensuite accéder aux variables et @property de cet objet comme n&#39;importe quel autre<br />[s setToto:@&quot;Tata&quot;];<br />s.titi = 54;
    
    J'ai supposé dans cet exemple que la classe/singleton MonSingleton avait une méthode [tt]-(void)setToto:(NSStirng*)val;[/tt] et une propriété [tt]@property(assign) int titi;[/tt]

    Voilà , tu utilises donc ça au même titre que tu utiliserais [tt]MyUILabel.text = @plouf;[/tt] ou [tt][MyUIButton setTitle:@tata forState:UIControlStateNormal];[/tt] par exemple, ou n'importe quelle autre méthode et/ou @property d'un objet Cocoa.
  • CéroceCéroce Membre, Modérateur
    21:19 modifié #3
    - Tu peux utiliser une variable globale comme tu le fais en C
    - Un singleton est une instance unique d'un objet. Si tu n'as pas besoin d'un objet, pas besoin d'un singleton.

    La question est plutôt: Pourquoi as-tu besoin d'une variable globale ? En général (ce n'est pas une règle absolue), l'utilisation de variables globales témoigne d'une mauvaise conception de l'application.

    Bref, dis-nous que tu veux en faire, nous allons t'expliquer comment t'en passer !
  • ClicCoolClicCool Membre
    novembre 2009 modifié #4
    dans 1257238619:

    - Tu peux utiliser une variable globale comme tu le fais en C
    - Un singleton est une instance unique d'un objet. Si tu n'as pas besoin d'un objet, pas besoin d'un singleton.

    La question est plutôt: Pourquoi as-tu besoin d'une variable globale ? En général (ce n'est pas une règle absolue), l'utilisation de variables globales témoigne d'une mauvaise conception de l'application.

    Bref, dis-nous que tu veux en faire, nous allons t'expliquer comment t'en passer !


    +1

    N'oubies pas, en particuliers, que tu as les NSUserDefault pour maintenir toute une collection de valeurs de préférences utilisateur.

    Mais en cas de réél besoin de quelques objets/valeures globales, n'oublions pas non plus qu'en dehors de créer un singleton pour "servir" des objects globaux, il y a dans quasiment toutes les appli une classe qui n'est jamais instanciée plus d'une fois et qui peut faire ça: l'Application Delegate, Que tu retrouve depuis n'importe où avec un simple:
    (MaClasseDelegate*) delegate = [NSApp delegate];
    
  • PhildesPhildes Membre
    21:19 modifié #5
    Merci pour vos conseils.
    Mais voici ce que je veux faire.
    J'ouvre dans un IBAction un NSOpenPanel qui me fournit un NSString path vers un répertoire donné.
    Je veux pouvoir accèder à  ce path et le compléter à  partir d'un autre IBAction.
    Or la variable initiale path n'est accessible dans le 2ème IBAction que si elle est globale.
    J'ai réalisé le projet en déclarant une variable char* globale dans le .h et en convertissant la NSString initiale en char* Cela fonctionne mais plante au bout de plusieurs réitarations à  cause d'un overflow (mémoire mal gérée). Et je n'arrive justement pas à  gérer la mémoire allouée au char* par un malloc/free quelconque.
    C'est la raison pour laquelle je voulais me porter sur un singleton, pensant mieux pouvoir gérer les espaces alloués.
    Vous aurez compris que je viens du C et que je ne fais que débuter avec Obj.C :)
  • ClicCoolClicCool Membre
    21:19 modifié #6
    dans 1257243012:
    .../...
    Je veux pouvoir accèder à  ce path et le compléter à  partir d'un autre IBAction.
    Or la variable initiale path n'est accessible dans le 2ème IBAction que si elle est globale.../...

    ?

    Si tes deux IBActions sont implémentées dans la même classe, tu n'as qu'à  ranger ta NSString (obtenue par ta première IBAction) dans une variable d'instance de cette classe non ?
  • CéroceCéroce Membre, Modérateur
    21:19 modifié #7
    Tu as un problème de conception ici. Nous, les vieux croûtons, avons l'habitude d'embêter les petits jeunes avec le paradigme Modèle-Vue-Contrôleur.

    Ce truc dit qu'il faut séparer:
    - les vues: ici tes NSOpenPanel
    => instanciées par le contrôleur

    - du modèle: l'objet qui a besoin des chemins des fichiers
    => instancié par ta sous-classe de NSDocument pour une application Document-based, ou par l'AppDelegate sinon.

    - en utilisant un contrôleur: une simple sous-classe de NSObject qui va afficher les NSOpenPanel, et une fois fermés, lire les chemins des fichiers et les affecter au modèle.
    => instancié par l'AppDelegate ou un autre contrôleur, selon la complexité de l'application.

    Je ne dis pas que c'est simple, mais il faut t'imprégner de ce principe utilisé à  outrance dans Cocoa.
  • PhildesPhildes Membre
    21:19 modifié #8
    J'ai suivi le conseil de Clicool et placé ma variable dans une Outlet que j'ai créée pour l'occasion. Et ça fonctionne.
    Mais je ne raisonne pas encore cocoa, pas évident de passer du C à  Obj.C :)
    En tout cas merci à  vous tous, c'est sympa de venir ici.
  • CéroceCéroce Membre, Modérateur
    21:19 modifié #9
    Oui, bien sûr ce que t'as dit ClicCool fonctionne.
    Par soucis de simplicité, il a retiré la couche "Modèle" du paradigme MVC.

    Tu vas vite venir à  un ensemble MVC complet, par exemple quand tu voudras enregistrer le chemin du dossier dans les préférences.
  • ClicCoolClicCool Membre
    21:19 modifié #10
    dans 1257260814:

    Oui, bien sûr ce que t'as dit ClicCool fonctionne.
    Par soucis de simplicité, il a retiré la couche "Modèle" du paradigme MVC.../...


    Oui, j'ai fait "au plus simple" sur ce coup là   :)
Connectez-vous ou Inscrivez-vous pour répondre.