variables globales
bofy
Membre
Bonjour
Je définis un singleton Common qui doit(devrait) me permettre d'accéder aux mêmes variables depuis n'importe quel endroit de mon code.
Sur un menu item de connexion, je crée une fenêtre qui établit une connexion avec une BdD pgsql : pas problème, tout se passe (apparemment) bien (NSLog ok dans la console de xcode), notamment le setter de l'identification de la connexion à la base de données, suivi d'un getter ok.
Sur un menu item de déconnexion, je crée une fenêtre, et là plus rien ne marche : il semble qu'il n'y a plus rien de global dans mon Common : impossible de récupérer l'adresse de la connexion avec son type, ce qui marche ci-avant.
Le fait d'utiliser plusieurs fenêtres casse-t-il le Common ? Je dis ça pour voir, mais je n'y crois guère.
En fait, je pense que je n'ai pas tout compris dans les singletons. Quelqu'un pourrait-il m'expliquer (la doc apple est pingre à cet égard).
Merci
Je définis un singleton Common qui doit(devrait) me permettre d'accéder aux mêmes variables depuis n'importe quel endroit de mon code.
Sur un menu item de connexion, je crée une fenêtre qui établit une connexion avec une BdD pgsql : pas problème, tout se passe (apparemment) bien (NSLog ok dans la console de xcode), notamment le setter de l'identification de la connexion à la base de données, suivi d'un getter ok.
Sur un menu item de déconnexion, je crée une fenêtre, et là plus rien ne marche : il semble qu'il n'y a plus rien de global dans mon Common : impossible de récupérer l'adresse de la connexion avec son type, ce qui marche ci-avant.
Le fait d'utiliser plusieurs fenêtres casse-t-il le Common ? Je dis ça pour voir, mais je n'y crois guère.
En fait, je pense que je n'ai pas tout compris dans les singletons. Quelqu'un pourrait-il m'expliquer (la doc apple est pingre à cet égard).
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Qu'est-ce qui n'est pas clair ?
AMHA tu gères mal ta mémoire, c'est ça le problème.
Le fait de faire trop de release d'un coup peut définitivement libérer ton singleton ce qui provoque un plantage lors de la tentative d'accès au singleton...
PS : J'espère ne pas avoir dit de bêtise, mais avec la mémoire c'est souvent ça qui pose problème...
Il ne faut bien sûr dans ce cas pas appeler alloc/init pour créer ton singleton, mais ton accesseur spécialisé, comme tu utiliserais "defaultCenter" pour le singleton du NSNotificationCenter, ou "sharedInstance" pour la plupart des classes singleton qu'on trouve déjà dans Cocoa... ou "sharedManager" dans le cas de l'exemple de code fourni par Apple.
Bien sûr j'applique la doc de singleton d'apple, dont je maintiens qu'elle est très succincte.
Voici des extraits de mon code
Dans ma 1ère fenêtre, j'appelle Common
Ca marche OK , cf dans la console xcode :
Dans ma 2ème fenêtre :
Plus rien ne marche, tout se passe comme si [common getConn] renvoyait n'importe quelle adresse, sauf celle définie dans la 1ère fenêtre : pour un vieux du C, cela me rappelle un problème de mémoire mal gérée. Faut-il mettre des retain, release, alloc, dealloc, autorelease, etc. Mais où ?
Merci
Peut-être :
-(void) setConn : (RNKDPostgreSQLConnection *) conn {
if(conn!= bofConn) {
[bofConn release];
bofConn =[conn retain];
}
}
Rha, j'aime pas cette technique :P
C'est tellement plus élégant et ça évite un test qui ne sert à rien 90,999% du temps !
Question de goût, sachons néammoins que c'est celle donnée par le script d'Apple (menu scripts>Code > Place Accessors Definitions on clipboard) Cela ne doit pas être si nul ...
Dans combien de cas sur 1000 tu fais un "set" avec le même objet qu'il y avait auparavant ? :P
Quand à Apple, c'est pas une référence, ils aiment bien faire des trucs inutiles
Preuve en est leur code d'accès de singleton où ils font un lock de mutex à chaque accès !
Au lieu de le limiter par un test bien moins coûteux :
Franchement l'une ou l'autre me semble parfaitement équivalent sauf pour une classe où j'utiliserais le setter 1000000 de fois, et où je pourrais gagner une microseconde ... ... mais là je me poserais la question de la structure de mon programme.
C'est surtout parce qu'avec la technique du retain / release / affectation, on gagne en lisibilité (des accolades en moins), et on gagne une ligne 8--)
Mais je te mets au défi de trouver un cas pratique " intelligent "Â où ça arriveÂ
Question de goût effectivement... Entre faire quelque chose d'inutile quasi-systématiquement, et quelque chose d'inutile un peu plus gros dans quelques cas rares, je préfère la seconde solution ! :fouf):
(Surtout quand la syntaxe est plus élégante...)
Quand le setter prend en argument un objet s'apparentant aux "constantes" une NSString, un NSIndexPath, une NSImage en cache, une NSColor , NSFont ...
Ceci dit, je ne défends ni l'un ni l'autre, je dis que cela n'a pas d'importance, et que c'est couper les spaghetti dans le sens de la longueur, sauf cas rare ou mal ficelé.
Concrètement, j'ai du mal à voir les cas pratiques :P
1. Pourrais-tu m'expliquer les lignes retain et release ?
2. Faut-il mettre ça dans tous les setter du singleton Common ?
C'est tellement plus élégant et ça évite un test qui ne sert à rien 90,999% du temps !
On incrémente le compteur de références du nouveau, on décrémente celui de l'ancien.
Pourquoi, tu faisais comment avant ?
Ben, je faisais sans retain, ni release... Et ça marche ! sauf dans le cas cité.
Explications STP sur ce qu'est un "setter classique", je n'ai rien trouvé dans la doc.
Tout est décrit ici dans la doc Apple ; tout ce qui est autour de la gestion mémoire en Cocoa (cette doc et ses voisines), c'est une base qu'il est indispensable de connaà®tre si tu ne veux pas faire de bétises ou te retrouver avec des cas comme ceux que tu viens de citer, donc il peut être bon que tu y fasses un tour si tu ne te sens pas à l'aise avec ces concepts ou petites subtilités.
Tu as probablement fait un "set" avec un objet auto-released... Du coup, il a été détruit peu après et quand tu as voulu y accéder, crash.
Je crois que je ne deviendrai jamais un pro de l'obj-C, ce qui n'est d'ailleurs pas mon but.
Je vais mettre des retain et autres un peu partout, même si ne comprends pas complètement bien pourquoi.
Par exemple, l'histoire de la laisse du chien (cité dans Hillegrass) me laisse rêveur : je n'ai jamais vu un chien avec plusieurs laisses tenues par des gens différents ! mais puisque ça sert de modèle...
Je ne pense pas que ce soit la bonne façon d'aborder le problème...
La gestion de mémoire en Obj-C est assez simple en somme! Sauf si tu ne fais et ne feras qu'un seul programme (celui-ci) et que toi seul l'utilisera, il faudra bien t'y intéresser un jour... (en utilisant la méthode que tu nous décris, ton programme va probablement grossir à l'utilisation, minutes après minutes)
Même si l'analogie avec le chien et la laisse est un peu "capillo-tractée", elle est assez convaincante, il suffit d'imaginer le chien et les laisses multiples pour se rendre compte du principe...
La programmation est un art demandant certaines qualités d'abstraction!
C'est une régression qui nous ramène au C, et encore. J'ai écrit des milliers de lignes en C sans avoir à me préoccuper de la mémoire: il suffisait de programmer correctement sans utiliser les "bidouilles" que le C permet.
Aujourd'hui, il semble qu'en objective-C il faille passer impérativement par des bidouilles plus tordues les unes que les autres. Exemple parmi le plus grossier : pourquoi a= b est une affectation d'adresse et pas d'objet ?
Somme toute, programmer en objective-C est du pur masochisme, imposé par apple, qui ainsi décourage tout développement individuel.
Pourquoi pas ada qui manipule de vrais objets et pas des adresses ?
La programmation objet est un petit monde qui permet à des milliers d'informaticiens théoriciens de passer des thèses universitaires à peu de frais en disséquant le sexe des anges, mais qui n'a jamais rien apporté aux programmeurs et qui introduit un monde d'instabilité qui explique les bugs récurrents de tous les systèmes et programmes informatiques.
Bien à toi
PS : je suis masochiste...
Parce que c'est comme ça, ça a toujours été et ça le sera toujours. La gestion de la mémoire est une constante du métier de programmeur.
Même en utilisant un GC, on n'est pas libre, car ça soulève d'autres problèmes (d'ordre par exemple).
C'est que tu n'as pas dû travailler avec des données sérieuses... Si tu bosses sur une image par exemple, tu la stockes sur la pile ? Il va faire la gueule ton programme !
On n'est plus à l'époque du Fortran où on était obligé de gérer le traitement des données avec des découpages super-optimisés pour la mémoire.
Parce que l'Objective-C n'autorise pas la surcharge des opérateurs (ce qui est à la fois une force et une faiblesse ; car la surcharge d'opérateurs permet de faire un peu tout et n'importe quoi)
C'est pas ce que se sont dit les milliers de développeurs qui s'y sont mis pour se faire des sous avec l'iPhone apparemment...
Ben... Parce que c'est comme ça, que veux-tu qu'on dise ???
Holà à à à à , ça sent la nostalgie ça... Les bugs récurrents ne sont pas dus à la programmation objet, mais au laxisme actuel.
C'est sûr que quand on utilisait les cartes perforées et que la machine mettait la journée à compiler le programme, il valait mieux être sûr de son truc et l'avoir relu 15 fois, fait exécuter à la main pour tous les cas etc. avant de l'envoyer ! :P
Certains de tes propos me laissent perplexes. ???
Tu programmais quoi en C? L'allocation dynamique est l'une des bases du C. Tu n'as jamais utilisé d'alloc,calloc,malloc, free??? Et il en découle bien sûr l'usage des pointeurs qui rebutent tant les débutants en C.
Ben il programmait peut-être en C comme en Fortan 77 (pas de pointeurs, gestion de mémoire uniquement sur la pile)Â
Donc Obj-C fait tout ce que C fait !
On ne peut pas vraiment parler de régression, puisque Obj-C n'est pas vraiment un nouveau langage.
Bah pour moi, programmer uniquement sur la pile en C, c'est de la bidouille, utiliser des variables globales c'est aussi extrêmement crade... Et c'est zeuh bidouille en C...
Tu insultes les premiers programmeurs qui devaient développer des trésors d'ingéniosité pour résoudre des problèmes avec ça... seule chose qu'ils avaient à disposition :P
Au passage, les puristes C vous direz qu'il n'existe ni pile ni tas en C. :P