NSMutableArray récalcitrant
Veillard
Membre
Bonjour,
J'ai un Array "profilProfondeur" déclaré en global. Dans cet array, je stocke un profil de plongée.
Deux fichiers : Carnet.m et Profil.m utilisent le même array. Lorsque je clique sur une des plongées dans ma TableView, j'arrive à afficher mon profil puis lorsque je clique sur la plongée suivante, le même profil reste affiché.
Ce n'est que lorsque je ferme mon document et que je l'ouvre à nouveau que je peux accéder à ce nouveau profil. :why?:
Que se passe-t-il ?
Merci d'avance
J'ai un Array "profilProfondeur" déclaré en global. Dans cet array, je stocke un profil de plongée.
Deux fichiers : Carnet.m et Profil.m utilisent le même array. Lorsque je clique sur une des plongées dans ma TableView, j'arrive à afficher mon profil puis lorsque je clique sur la plongée suivante, le même profil reste affiché.
- (IBAction)handlePlongeeClick:(id)sender<br />{<br /> currentIndex = [sender selectedRow];<br /> if (currentIndex == -1) return;<br /> <br /> profilProfondeur = [[NSMutableArray arrayWithArray:[[tableauDesPlongees objectAtIndex:currentIndex] objectForKey:@"profil profondeur"]] retain];<br /> <br /> [self editFields];<br /> [self updateUI];<br />}<br />
Ce n'est que lorsque je ferme mon document et que je l'ouvre à nouveau que je peux accéder à ce nouveau profil. :why?:
Que se passe-t-il ?
Merci d'avance
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
C'est un array enregistré dans un fichier que j'utilisais dans deux classes.
J'ai résolu le problème en ouvrant le fichier dans lequel est contenu l'array que quand j'en avais besoin pour faire des modifs dedans, ensuite une fois les modification faites, j'enregistrais l'array dans le fichier avant de le libérer. Et ceci dans les deux classes.
Je ne sais pas si c'est possible dans ton cas de faire comme j'ai fait, car c'est un array dont je récuperais seulement les valeurs a l'initialisation, et que je modifiais quand nécessaire, alors que toi je pense tu t'en sers pas mal de fois dans ton soft. En suivant ma technique, peut-être peut-tu copier l'array chargé dans un autre array avant de le libérer afin d'éviter le conflit entre les deux classes ?
Je pense qu'il existe d'autres techniques pour remédier à ce problème, mais lesquelles ? ???
Quelqu'un a-t-il une solution ???
Merci
Non j'ai pas la soluce car déjà je ne comprends pas pourquoi tu fais une copie de ton tableau, pour ta classe profil.m, un pointeur sur ce tableau devrait suffire.
Et justement vérifie que ce pointeur que tu initialises dans handlePlongeeClick, c'est bien le même que tu utilises dans profil.m.
Sinon un banal reloadData
Voilà , j'ai essayé plusieurs techniques comme celle d'Eddy58 qui m'a suggéré de copier un array dans un autre array.
Sinon, ce que j'ai fait, c'est déclarer l'array dans les 2 classes :
- dans "Carnet.h"
- puis dans "Profil.h"
- puis dans "Carnet.m", je charge les données dans l'array :
- enfin, j'utilise l'array pour tracer mon profil dans "Profil.m"
Peut-être ai-je oublié quelquechose ???
Avec ce que propose mpergand, la solution est en effet de peut-être utiliser un seul et même pointeur, tu ouvres ton array dans Carnet.m, puis, en codant proprement et en supprimant ta variable globale (tu vois je suis très partisant de l'encapsulation ;D), tu te fais une méthode accesseur dans carnet.m, et ensuite tu demandes à l'accesseur le pointeur de ton array dans Profil.m...
Je suppose que je dois encapsuler l'array comme ceci dans "Carnet.m":
Après j'avoue que je ne sais pas comment faire (le bouquin un un peu sec sur le sujet) :P
Si tu charges plusieurs documents, ils partageront la même variable profilProfondeur ???
Il n'y a aucune raison d'utiliser ce genre de variables en prog objets, à part pour définir des variables de classe ( en ObjC), ce qui n'est pas le cas ici.
Donc tu va définir une variable d'instance pour ta classe profil.m avec un bel accesseur et dans handlePlongeeClick faire: currentProfil.setProfileData(profileArray);
De plus ta classe profil est un NSView ??? ben :why?: tu dessines quelque chose de spécial dans cette vue ?
En théorie toutes ces classes devraient être des classes contrôleurs, bon ça c'est pas le plus grave, car je crois qu'il y a un gros problème de structure/logique dans ton prog,
Le plus simple serait de tout gérer dans Carnet ?
le retain est inutile, je crois bien, tu fais un release où:
profilProfondeur = [[[tableauDesPlongees objectAtIndex:currentIndex] objectForKey:@profil profondeur] retain];
le tableau est déjà retenu par le dictionary, il me semble.
Je pensais qu'en mettant cette variable en global, on pouvait accéder à son contenu à partir des deux classes.
Oui, je trace le profil dans la View.
Je vais tenter les accesseurs
Oui , mais global veut dire global au programme tout entier.
Mais si c'est un NSView, c'est un setNeedsDisplay qu'il faut faire pour actualiser l'affichage...
J'ai voulu séparer "Profil.m" pour deux raisons :
- la première c'est que "Carnet.m" comporte plus de 1500 lignes ;D
- la seconde parce que c'est une NSView.
J'ai essayé les accesseurs sans commentaires je bidouille sans y comprendre grand chose ou si peu :P
Ce que j'ai fait :
- dans "Carnet.m", j'ai écrit :
Puis quid des instructions à écrire dans "Profil.m" pour récupérer mes données ???
Ensuite, toujours dans Carnet.m, tu initialises ton array comme tu veux, ensuite dès que tu as fait l'initialisation de ton array, tu fais :
Voilà pour carnet.m. Ensuite, pour ta classe Profile, il te faut tout d'abord informer ta classe pour qu'elle puisse accéder à l'accesseur. Dans Profile.h, rajoute ceci en début de listing après les directives #import :
Puis dans Profile.m, tu rajoutes un import :
Et puis enfin, pour récupérer ton array, tu utilises l'instruction suivante, à mettre ou tu le sens tout dépend le fonctionnement :
Et puis effectivement, comme le dis mpergand, tu as une sous-classe de NSView, donc quand tu as terminé tes opérations de tracé, il faut rafraà®chir ta view :
Voilà espérons que ca marche.
C'est dans profil.m qu'i faut déclarer profilPronfondeur, pas dans carnet.m
donc tu déclares une variable d'instance dans profil.h:
NSArray* profil;
et tu implémentes dans profil.m, la methode:
-(void) setProfilData:(NSArray*) prof
{
profil=prof;
}
Donc dans carnet.m tu as besoin d'un outlet sur la vue profil et dans handleClick tu fais:
NSArray* profilProfondeur = [[tableauDesPlongees objectAtIndex:currentIndex] objectForKey:@profil profondeur];
[profilView setProfilData: profilPronfondeur];
[profilView setNeedsDisplay:YES];
Je vous tiens au courant...
Oui tout dépend comment on voit les choses, effectivement côté fonctionnement je n'ai pas pensé pareil mpergand. Ta méthode a l'air plus propre je pense.
Favouille, tu as encore quelques progrès à faire en programmation objets
Eddy:
profile.m n'a besoin de connaà®tre Carnet.m
c'est pas très objet ça, un peu bricolo j'dirais ;D
[edit]
no comment
Oui tout à fait, c'est pourquoi je trouve ta méthode plus clean.
Pour répondre à mpergand, j'ai déclaré l'arré dans Carnet parce que je l'utilise plusieurs fois dans d'autres situations (ex : ajout de l'array dans un dictionary...) de plus, à la compilation il ne me met 9 erreurs : "profilProfondeur undeclared" :-\
Avec la méthode d'Eddy, j'ai :
Que fais-je sachant que l'array est plusieurs fois utilisé dans Carnet...
Sinon, le cas échéant, tu peux utiliser une notification pour transmettre ton pointeur. J'utilise souvent cette méthode, elle marche à coup sûr, et elle n'est pas lourde à mettre en oeuvre....
Je rectifie : beaucoup de progrès ;D
La preuve : à la compilation je bloque sur "profilView" de :
Je ne sais pas à quoi ça correspond...
Je suis à fond dessus...
Bon, c'est pas un problème, tu as donc une variable d'instance dans carnet.m qui contient le tableau des données du profil courrant, donc tu fait:
L'important est que profilView sache avec quelles données travailler
Reste que j'ai une erreur de compil avec "profilView" qui est "undeclared"
[edit]
ha oui tu l'as appelée Profil !!
Dans carnet.h j'ai déclaré : "NSView *profilView", puis dans IB j'ai fait le lien entre "profilView" et la zone de tracage. Je pense que c'est ça qu'il fallait faire :-\
J'ai compilé et ça marche ! :brule: :brule: :brule:
Par contre, l'ancien profil n'est pas effacé, tout se superpose petit à petit...
???
ça devrait aller mieux !
Pour le problème de redessin, je pige pas bien non plus
Oui
En ce qui concerne les dessins, à chaque fois que je clique sur une plongée, le profil correspondant est correstement tracé mis à part que le ou les précédents profils ne sont pas effacés...
Par contre, en ce qui concerne les graphiques, je vais voir si il n'y a pas une fonction pour effacer la View à chaque nouvel appel.
En tout cas merci beaucoup pour ton aide précieuse sans oublier Eddy. :trinque: :trinque: :trinque: