Trier une Tableau avec un NSDictionary ?
karousel
Membre
Bonjour,
Je vous expose mon problème.
J'ai un programme qui présente une tableView (le contenu de la tableView est un NSMutableArray). Le type de variables sont des String.
J'ai une méthode qui attribue un certain nombre à chacune des variables de mon tableau. J'enregistre le tout dans un autre NSmutableArray (avec un NSdictionary).
Dans mon dictionary, j'ai donc : "nom"->variablesNom et "numéro"->numerosAttribués.
Tout est Ok, dans mon tab1 j'ai mes noms.
Et dans mon tab2, jai mes noms avec des numéros. J'utilise tab2 et effectue un triage en fonction des numéros.
Jusque la, sa va, mais après j'aimerais modifier mon tab1 afin que les noms aient le même ordre que mon tab2 (puisque ce sera mon tab1 qui sera affiché à l'écran). Mais la je sèche totalement ?
Est-ce que quelqu'un aurait une idée ?
Merci
Je vous expose mon problème.
J'ai un programme qui présente une tableView (le contenu de la tableView est un NSMutableArray). Le type de variables sont des String.
J'ai une méthode qui attribue un certain nombre à chacune des variables de mon tableau. J'enregistre le tout dans un autre NSmutableArray (avec un NSdictionary).
Dans mon dictionary, j'ai donc : "nom"->variablesNom et "numéro"->numerosAttribués.
Tout est Ok, dans mon tab1 j'ai mes noms.
Et dans mon tab2, jai mes noms avec des numéros. J'utilise tab2 et effectue un triage en fonction des numéros.
Jusque la, sa va, mais après j'aimerais modifier mon tab1 afin que les noms aient le même ordre que mon tab2 (puisque ce sera mon tab1 qui sera affiché à l'écran). Mais la je sèche totalement ?
Est-ce que quelqu'un aurait une idée ?
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Pourquoi ne pas avoir que le tableau de NSDictionaries {nom,numéro} ?
Comme ça tu n'as qu'un tableau. (Et ensuite tu tries ce tableau avec un NSSortDescriptor pour lui dire de trier en utilisant la clé "numero" du dictionary pour chaque entrée du NSArray)
Et maintenant tout mon programme repose la dessus.
Pourquoi, est-ce que c'est grave de recréer des tableaux, au niveau mémoire ?
Vu que je test sur mon iphone, cela semble assez performant encore.
Merci de votre aide, mais je viens de trouver :
Niveau optimisation, je sais qu'il me reste beaucoup à faire.
Je croie que le pire c'est que je réutilise au moins 5 fois dans mon programme des if{} else... avec un certains nombres de variables.
Y aurait-til pas un moyen de l'écrire une seule fois dans une méthode, et ensuite de les réutiliser en écrivant juste la méthode.
Car a chaque fois que j'en ai besoin ces dans des méthodes précises (et je vois pas comment appeller une autre methode dans une méthode) .
Et dans les "define" je ne pense pas que cela marche
Quand tu veux implémenter une recherche sur un tableau, effectivement il te faut séparer ton modèle en 2 : un tableau contenant toutes tes données, et un tableau contenant uniquement les résultats de la recherche.
Mais à moins que j'ai mal compris ton premier post, j'avais cru capter que tu avais un tableau avec les noms, un tableau avec les notes, et un tableau avec des NSDictionary contenant les noms et les notes... Et là ça fait beaucoup, non ?
En fait je pense que je vois pas trop clair dans ton modèle, tel que tu l'as décrit. Des bouts de code seraient plus parlant.
D'ailleurs j'ai le même souci pour ton problème de "if/else" recopié 5 fois dans ton code, je pense qu'un extrait de code serait plus simple (parce que sinon je ne vois pas ce qui te pose problème dans le fait de créer une méthode pour mettre ton bout de code, et d'appeler cette méthode depuis les méthodes qui ont besoin de l'utiliser ? C'est du basique en programmation pourtant, tu appelles juste une méthode, donc je suppose que ton problème est plus compliqué que ça ?)
Et je le classe par ordre de plus petit au plus grand
voici mon code :
Pour les if/else, j'ai enlevé car j'ai plus de 50 valeurs de longitudes et latitudes , ça fait :
if(lieu1) {
longit=...;
lat=...;} else if(lieu2){
....}
Je veux dire par la que j'ai besoin plusieurs fois dans mon programme des valeurs de longitudes et latitudes... et le repeter, je trouve ça assez lourd
Tu devrais éviter de faire des boucles et des if partout !
Pour la recherche, plutôt que de faire une boucle, je te conseille plutôt d'utiliser les NSPredicate et la méthode filteredArrayUsingPredicate.
Un predicat du genre ("SELF.name CONTAINS %@",searchText) sur ton tableau contenant tes NSDictionary {name,valeur} et hop, en 2 lignes c'est filtré.
Pour tes if/else, pourquoi tu n'as pas un NSDictionary contenant comme clé tes lieux, et en valeur des CLLocation ou CLCoordinate2D ou qqch du genre ? Et comme ça pareil, en une ligne tu peux récupérer les latitudes/longitudes de ton lieu, au lieu d'avoir 50 lignes avec des if/else.
Ben donc je devrai créer une NSDictionnary avec mes valeurs et noms, et ensuite je vais chercher dedans comment ?
Je te parlais de la boucle [tt]for(NSString* name in variableTableau)[/tt] que tu fais plus haut que j'aurais fait plutôt avec un simple NSPredicate.
Et sinon j'ai du mal à voir pourquoi tu t'embêtes également à faire une boucle [tt]for(int j=0;j<[variableAAfficher count];j++)[/tt] et à calculer la distance avec ta formule alambiquée ? Pourquoi ne pas soit utiliser un bête pythagore -- à moins que tu veuilles vraiment prendre en compte la courbure de la terre et les subtilités de la projection Mercator -- ou surtout, beaucoup plus simplement et efficacement, utiliser la méthode distanceWithLocation de CLLocation pour calculer la distance entre 2 points GPS (2 CLLocation) ?
Et surtout, après, est-ce que tu utilises cette distance pour autre chose ? Sinon pourquoi la calculer et la stocker, pourquoi ne pas directement la mettre dans le selector de ton NSSortDescriptor ? Tu pourrais ainsi n'avoir que ton tableau de lieux (avec leur nom, position, etc), et appliquer un NSSortDescriptor dessus qui trie en utilisant non pas une clé existante dans tes objets représentant tes lieux, mais en utilisant un @selector qui va calculer la distance de ce lieu avec la position de l'utilisateur.
Au final, pour moi tu as besoin de :
- Une classe "Lieu" qui représente un de tes POI, avec un nom, une position CLLocation, les infos propres à tes POI éventuelles...
- un NSArray de lieux contenant tous tes lieux
- un NSArray de lieux contenant tes lieux filtrés, résultats de la recherche, triés par distance.
Pour obtenir le 2e NSArray à partir du premier et d'un texte de recherche, tu appliques un NSPredicate dessus du genre "SELF.name CONTAINTS %@" via filteredArrayUsingPredicate, puis tu tries le résultat par distance avec sortedArrayUsingComparator (si tu es sur iOS4 ou supérieur, sinon sortedArrayUsingSelector) et en lui passant un bloc de code qui va calculer la distance entre ton point et la UserLocation pour faire ce tri. Ta distance ne sera ainsi calculée que pour le tri, tu n'auras pas besoin de te construire une structure intermédiaire en calculant toi-même la distance pour chaque objet de ton tableau en créant un tableau avec cette clé supplémentaire ou tout ce tralala.
Oui j'ai déjà modifié ma ma façon de calculer la distance (c'est vrai que il y a plus simple):
J'ai un NSdescriptor à la suite, car je peux pas le mettre directement dans ma boucle, sinon ça ira pas.
Et pour la notion de NSPredicate, j'ai un peu de mal à la comprendre, c'est pour ça que j'utilise des boucles.
Comment je pourrai créer mon if/else d'une autre façon ?
Ainsi tu n'as pas besoin de stocker la distance dans tes tableau de POIs filteredPOIsByDistance ou autre. Tu filtres ton tableau, et au moment de le trier tu lui files le NSComparator (block de code) qui va lui dire comment comparer chaque objet de ton tableau l'un avec l'autre pour savoir lesquels mettre avant les autres, bref dans quel ordre les trier.
Si tu développes pour une version de iOS <4.0, les blocks ne sont pas disponibles (c'est une nouveauté de iOS4), mais tu peux utiliser un @selector ou même un une fonction C à la place.
Comme ça c'est quand tu lui demandes de trier que tu lui expliques comment trier (calculer la distance à ce moment là ), ça t'évite d'avoir à la calculer en amont pour tous tes objets, puis à trier sur le résultat ensuite, tout ça pour ne plus jamais te servir de la distance après...
Le truc c'est que j'ai réalisé un programme, et maintenant je pas changer une partie apres sa fera buger le reste.
En gros, j'ai une une classe annotation pour definir mes annotations.
Une classe restaurant qui contient les noms, coordonnées etc...
Une UIView RootViewController dans laquelle je reprend les annotations à partir d'une méthode de la classe restaurant (un tableau que j'envoie directement pour créer mes annotations). ca me permet de les afficher sur la carte.
Et un Tableau qui recupere juste les noms de tout les restaurant (de la classe Restaurant). Et je m'en sert pour faire ma tableView.
Mais dans ma classe RootViewController, je ne peut pas récupérer chaque POI, puisque ça me renvoi un tableau.
Donc la méthode CLL location ne peut pas s'initialiser, si ?
Mais je viens de me rendre compte, que la conception est de mon programme vraiment pourrie. Le tableau que je recupere ne contient que les noms, d'ou les if/else que je repete pour associer chaque noms à leurs cordonnées.
Je suis vraiment perdu la...
Pourquoi ne pas simplement faire en sorte que ta classe restaurant se conforme au protocole MKAnnotation ?
Faut savoir, c'est une UIView ou un ViewController ? Si tu fais encore cette confusion c'est que tu n'as pas encore bien cerné le MVC pourtant principe de base des applis iOS... Si Restaurant se conformait direct au protocole ça serait pas plus simple?
Quel intérêt ? Pourquoi ne pas manipuler directement le tableau de restaurants pour remplir ta TableView ? Ce qui serait bcp plus flexible, plus en adéquation avec le MVC, et te permettrait même à terme de faire évoluer ta TableView pour afficher éventuellement d'autres infos dans chaque cellule, y'a tout à perdre à se limiter à un tableau de noms
Bah du coup vu comment tu as fait avec ta conception alambiquée et ton extraction uniquement des noms, en effet ça doit être une grosse galère... Tu aurais gardé ton tableau de Restaurant (au lieu d'avoir un tableau de restos et un tableau uniquement avec le nom des restos ce qui fait un peu double emploi) t'aurais pas eu ce problème ça t'aurait fortement facilité les choses là encore
Gné? ??? tu entends quoi par "la méthode ne peux pas s'initialiser ? (ça veut pas dire grand chose ta phrase)
Mais en effet si tu as un tableau de nom et pas un tableau de Restaurants, là encore tu n'as donc pas les CLLocation associés à tes restaurants vu que tu n'as gardé que le nom (j'ai toujours pas compris pourquoi, l'intérêt de cette extraction) donc t'auras du mal à calculer la distance du resto en question avec la userLocation!
Ah ben ça clairement ça m'a l'air un beau boxon looool
A ce stade je crois qu'il faut mieux reprendre la conception depuis le début. Dans tout projet il faut passer du temps sur la conception et l'architecture avant de faire du dev et de mettre les mains dans le code. Manifestement, tu as précipité les choses :P
Franchement, tu aurais gardé juste ton tableau de POI (tableau de Restaurants) et tu te débarasses une fois pour toutes de ton "tableau de noms" dans lequel tu ne gardes que les noms, et ça va déjà te résoudre bcp de problèmes que tu as évoqué dans tes posts depuis le début. Tu noteras que c'est un peu ce que je te conseille depuis le tout début, et j'avais donc bien cerné le problème en te disant "pourquoi avoir tes données [tes noms de resto] en double en plusieurs endroits, dans plusieurs structures", pourquoi ne pas avoir juste un tableau de lieux/POI et basta plutôt que d'avoir un tableau de lieux, un tableau de noms de ces lieux, etc. donc tu auras suivi mes conseils dès le début, on en serait pas là :P ;D
J'utilise la classe annotation pour initialiser mes "restaurants". Dans ma classe annotation, c'est du style monAnnotation*Resto1=....
Pardon mon RootViewController c'est une ViewController (j'ai eu un bug car était en train de faire un UIview).
Comment ça, si Restaurant se conformait direct au protocole ? je ferait un protocole dans ma classe annotation ?
Manipuler directement le tableau de restaurants pour remplir ta TableView, je ne peut pas. Car j'afficherai comment juste les noms des annotations dans ma tableView ? parce que le tableau contient les coordonnées, un identifiant .....
Le truc c'est que je vois pas comment on peut trier un tableau en fonction du type de valeurs à l'intérieur. Serait-il pas plus judicieux de créer un Dictionnaire ?
Ce que j'entend par ma méthode CLLocation qui ne peut pas s'initialiser. C'est que je les récupères comment mes coordonnées des annotations à partir d'un tableau qui contient des MKannotations (je serais pas dans quel ordre ça va être traité).
Que avec userLocation, j'ai juste a prendre les 2 coordonnées et calculer la distance. Je pense que ce n'est pas le plus gros de mes problèmes lol.
Si j'avais directe un dictionnaire avec les noms et coordonnées, sa résoudrai à la fois mon problème des if/else et ce problème de créer des tableaux qui servent à rien... Non ?
Oui je sais, que tu avais raison. Mais le truc c'est que j'ai déjà plein de fonction à mon programme. Et je peux pas tout recommencer.
C'est pour ça comme tu l'a dit, il faut que je garde mon tableau avec les annotations.
Et je pense ce qui résoudrai le reste des problème serait de faire un Dictionnaire, avec les noms des lieux et leur coordonnées ?
Merci de prendre le temps de me répondre, c'est vraiment sympa.
Heu ? Quel est le problème avec ce cas là ? Je vois pas. Il suffit dans[tt]tableView:cellForRowAtIndexPath:[/tt] quand tu configures ta UITableViewCell de mettre un truc genre tout simplement, qu'est ce qui te pose souci là dedans ?
D'ailleurs en gardant donc ton NSArray de Restaurants listeRestaurants " au lieu d'un NSArray de noms que tu as l'air de tenir à garder j'ai toujours pas compris pourquoi " ça te permet si tu le souhaite d'extraire d'autres infos, comme afficher justement la distance à laquelle se trouve le resto, avec un code genre[tt]cell.detailTextLabel.text = [resto.location distanceFromLocation:currentLocation];[/tt], etc.
Bien sûr il faudra choisir un UITableViewCellStyle compatible avec l'utilisation de detailTextLabel lors de sa création, mais bon tout ça est expliqué dans le TableView Programming Guide... que j'espère tu as lu... sinon il faut que tu ailles le lire de toute urgence !
Bah avec un NSSortDescriptor, en lui passant la clé sur laquelle tu veux trier par exemple. Ou avec le code que je t'ai mis dans les posts précédents avec sortedArrayUsingComparator ou autres méthodes décrites dans la doc de NSArray dans la partie "sorting the array" de la doc qui liste toutes ces méthodes là .
Bah oui C'EST CE QUE JE TE DIS DEPUIS LE DEBUT !!!
Il te faut un NSArray d'obejts Restaurant et c'est tout. Chaque restaurant possédant un nom, mais aussi un CLLocation indiquant sa position, et toute autre info relative au restaurant (son adresse postale par exemple, son téléphone, une image qui lui est associée, je sais pas, tout ce que tu veux, ça dépend de ton modèle de données et de ton architecture que tu as prévu dans ton diagramme UML... quoique je doute fort que tu en aies fait un, malheureusement, et ça se resent)
Alors je peux pas grand chose pour toi.
Il faut penser ton programme dès le début avec une architecture structurée et modulable. Sinon tu te retrouves à faire des patchs de partout, à avoir des trucs alambiqués juste pour contourner des problèmes, et au final à avoir un code incompréhensible et pas logique et programme instable (et qui risque de planter et d'être difficile à déboguer) et un truc pas évolutif du tout.
C'est pour ça qu'on fait des études de spécifications et d'architecture logicielle pour réfléchir à l'organisation d'un projet avant de se lancer tête baissée dans l'écriture du code.
Si tu ne veux pas réécrire ton code, vu comment ton architecture est bancale, tu ne peux pas y faire grand chose.
Ce que je ne comprends pas c'est que tu me dis que tu as déjà une classe Restaurant et un NSArray de Restaurants, donc je vois pas pourquoi tu ne pourrais pas le réutiliser à partir de là et adapter juste la partie de ton code qui gère l'affichage de la carte (si tu as suivi le MVC en plus c'est simple, c'est l'avantage du MVC c'est que c'est modulaire... Si tu n'as pas respecté un minimum une architecture propre et MVC, là c'est sûr tu vas galérer, c'est pas en empilant des planches n'importe comment qu'on fait une maison)
Ah associer les nom comme ça dans une tableView, bien vu j'y avais pas pensée (je suis un peu borné des fois lol).
Ouai malin, mettre "cell.detailTextLabel.text = [resto.location distanceFromLocation:currentLocation];" pour avoir la distance dans la tableView c'est super intéressant.
Mais enfait moi je butte sur la façon de reprendre mon tableau d'annotation et de pouvoir sortir que certaines parties.
Par exemple comment je vais pouvoir récupérer une annotation particuliere de mon tableau d'annotations ?
Et quand tu parle d'un "NSArray d'objets Restaurant", si je le fait à partir d'un tableau d'annotations c'est possible ? ou je peut m'en passer (car mon tableau d'annotations à forcément tous les objets restaurant dedans).
Oui c'est bien ce que tu dit, je peux me servir de mon tableau de Restaurants.
Je pense que mon programme est récupérable, la cause de ces problèmes est juste la gestion de tableau à partir de ma classe Restaurants.
Donc si je suis tes conseils, je ressort avec un seul tableau de ma classe restaurants. Dans ce tableau, il n'y que des annotations.
C'est la que je comprend pas..
Mon tableau contient des éléments sous forme de MKannotations, et je vois pas comment on peut obtenir une valeur particuliere de ces annotations contenu dans mon tableau.
Admettons, mon tableau contient des annotations et se nomme tableauRestaurant.
Voila, là j'arrive à récupérer le titre, donc je me sert que d'un tableau au lieu de 2.
Mais le truc c'est que j'arrive que à la récupérer à un index précis, je peux pas tout avoir (sans mettre atIndex:1 puis 2 puis 3....) ?
Je peut utiliser une boucle mais if/else (mais la je suis dans l'optique de rendre le code plus léger et clair).
Et si je l'utilise dans ma tableView, avec comme index indexpath.row, j'ai une erreur (car le programme pour créer la tableView essaye de parcourir le tableau à des index qui existent pas de mon tableau).
Si j'arrive à faire ça, j'ai plus besoin d'avoir tous mes autres tableaux qui servent à rien, de même pour les if/else (à ce moment là je n'aurai plus qu'à parcourir le tableau), et je pourrai utiliser CLLocation (vu que ce sera un tableau d'annotations).
Enfait j'ai une classe annotation qui permet de créer une annotation.
Ensuite une classe Restaurant qui est initialisée avec la classe annotation (donc ce sont des annotations) :
Et cette classe retourne un Array d'annotations (ici c'est arrayOfAnnotations).
Ce arrayOfAnnotations je le récupère dans mon RootViewController. Et je le range dans un array dans mon RootViewController :
Et après mon problème c'est pour le lire, je peux ressortir chaque valeur de mon tableau, mais avec une boucle for :
Je peux garder ce bout de programme pour lire le tableau, mais ça me fait de nouveau plein de boucles.
Si c'est pour afficher dans ta TableView, encore une fois ce n'est PAS nécessaire, tu peux directement utiliser ton tableauAnnotations.
Je ne vois aucun intérêt, d'après tes cas d'utilisation que tu as exposé, à extraire du tableau d'annotations un tableau contenant uniquement leur titre. A mon avis tu n'en as pas besoin, je ne vois pas dans quel cas ça te serait utile.
Maintenant si tu veux vraiment n'extraire que les titres de ton tableau d'annotation, là encore nul besoin de boucles, il suffit d'utiliser le KVC (cf doc).
Ben je veut extraire car j'en ai besoin pour afficher le titre dans mon tableau (pour la recherche).
Et que j'ai appris à faire une searchBar avec 2 tableaux :
-celui initial avec toutes les données (titres) dedans
-Second, qui permet de faire la recherche
Apres la je fait des boucles, c'est déjà beaucoup mieux qu'avant (car je n'ai plus mes if/else), et que mon programme est plus simple à comprendre.
Le seul truc qui fonctionne pas maintenant, c'est comment calculer la distance entre user.location et l'annotation. Je doit récupérer le titre sur lequel on à cliqué et le comparer avec toutes mes annotations. Ca me fait 3" for" imbriqués
T'as toujours pas compris qu'on pouvait faire [tt]cell.textLabel.text = [listeRestaurants objectAtIndex:indexPath.row].name;[/tt] alors que je te l'ai indiqué plein de fois dans les messages précédents...
Gné ? Tu aimes vraiment te compliquer la vie, toi...
Va falloir que tu révises un peu quelques cours d'architecture logicielle, sinon tu vas vraiment jamais t'en sortir.
Mais grâce à toi, mes problèmes par rapport aux annotations sont résolus.
Donc j'ai bien compris que reprendre un tableau suffit largement, et c'est ce que j'ai fait.
Mais par la suite, de ce que j'ai appris en m'exerçant à travers divers tutos. Pour faire une recherche if faut un Array de base, et un Array de "recherche".
Donc j'ai mon Array que maintenant je crée directement dans la méthode de recherche (de searchbar).
On va dire que ça ma grandement simplifié par rapport à avant, et que c'est déjà bien. Mon code pour la tableView :
La tout est nikel, sauf que je ne peut pas tronquer ma distance puisque qu'elle est en format %@ et non %f.
Pour la seconde partie, avec le calcul de distance, je n'arrive pas à le faire autrement :
Ici, je pense que j'ai quelques tableaux qui servent à rien. Mais je n'arrive pas à simplifier (je pense que je vais me contenter de ça, c'est déjà beaucoup mieux construit qu'au début). Le truc c'est qu'il faut obligatoirement un NSArray pour la ligne sortedArray, donc je peux pas mettre directement mon tableau variableAAfficher (qui est le tableau de "recherche" NSmutableArrray).
Mouais y'a encore du boulot !! Tu cumules les trucs illogiques toi, je sais pas comment tu raisonnes mais tu m'as l'air adepte du "pourquoi faire simple quand on peut faire compliqué et se prendre la tête" !!
[tt][[variableAAfficher valueForKey:@lieux] objectAtIndex:indexPath.row][/tt] ==> t'extrait, depuis ton tableau variableAAfficher, un tableau ne contenant que les lieux... (ce qui prend un peu de temps quand même)... tout ça pour ne prendre que l'objet à un index donné ensuite. Du coup en terme de perfs c'est tout ce qu'il ne faut pas faire. D'autant que plus loin tu fais encore la même chose avec "distance".
Bah oui justement, pourquoi tu utilises %@ et passes directement le NSNumber encapsulant la distance justement ? Pourquoi ne pas utiliser %f et la floatValue ?
Bon là j'abandonne. J'ai expliqué plein de fois comment construire ton sortDescriptor pour éviter d'avoir à calculer la distance en amont, et même si tu veux la calculer en amont, déjà les NSFastEnumeration sont bien plus efficaces que les boucles for standard, mais en plus je comprends pas pourquoi tu t'entêtes à faire une double-boucle for, alors que si ton architecture logicielle était bien construite tu aurais directement les références à tes restaurants dans tes annotations ou vice-versa. (Je serai curieux de voir le diagramme UML de ta couche Modèle de ton MVC, ça doit être un vrai boxon, tu m'étonnes que tu aies des trucs alambiqués avec ça)
Je débute seulement, et à la base je suis plus orienté Réseaux et télécommunications. C'est pour ça que la programmation c'est pas mon fort.
Je vais essayer d'expliquer ma façon de raisonner.
-Concernant la recherche, je comprends pas ce que l'on entend par un tableau filtré. Justement à la base j'ai un tableau d'annotations et je prend ce qui m'intéresse (ici les noms de lieux).
Enfait, je me dit, pourquoi reprendre un tableau contenant des informations supplémentaires (qui me serviront pas) et le balader dans mon programme ? pour moi je trouve que c'est gaspiller (les autres infos je m'en sert pas, j'ai juste besoin des noms et des distances qui sont rangés dans mon tableau "variableAAfficher").
-Ensuite par rapport à la tableView. J'ai bien remarqué qu'il y a un truc qui va pas.
Et pour [[variableAAfficher valueForKey:@lieux] objectAtIndex:indexPath.row], j'ai toujours appris à faire comme ça. Enfait si je fait pas mieux, c'est surtout par manque de connaissance encore.
De ce que j'ai pu comprendre avec le "KVC", pour avoir accés à la lecture, il faut déclarer une propriété. Et la pareil, vu les exemples assez mince que je trouve, je vois pas du tout ce que ça m'apporterait.
-Récupérer l'objet Restaurant correspondant à la cellule à afficher et ENSUITE demander à cet unique objet restaurant uniquement ses propriétés ?
J'ai compris que c'est le tableau qui vas pas. J'ai voulu faire comme ça à la base, ma distance est maintenant comprise dans ma classe restaurant. Mais le truc c'est qui je peux pas reprendre mon tableau de départ, si j'affiche, il va y avoir toutes les valeurs restaurants et pas celles recherchées.
En gros, j'envoi le tableau "VariableAAfiicher" qui est triée déjà et contient que les valeurs qui m'intéresse. Si j'envoi mon tableau d'annotations, je peux le trier aussi, j'arrive à l'afficher aussi. Mais le seul truc c'est que dans la tableView ma recherche ne sera pas bonne. J'aurai toutes les valeurs et non celles recherchées.
-Puis, pour afficher la distance. Oui j'étais totalement à coté, c'est bon j'ai refait.
-Dans la partie calcul de distance. J'ai essayé de le faire à ta façon, mais je n'ai pas réussi. Enfait lorsque j'écrit mon code, j'essaye de le comprendre. Et celui que tu m'a donné, bien que trés complet, je n'arrive pas à l'instancier correctement.
fiteredPOIs correspond bien à variableAAfficher. poi1 et poi2 je vois pas du tout ce que je peut mettre vu que j'ai plus de 2 restaurants.
Et des diagrammes UML, c'est un peu compliqué on va dire.
Enfait c'est de le cadre de mon stage de fin d'année. Et le patron m'a pas donné un programme précis. On va dire à la base je devais faire une carte avec des annotations (sur differentes plateformes). Ensuite ça a évolué pour faire quelque chose de plus complexe sur l'iphone, qui donne des informations détaillés, puis itinéraire... puis une searchbar avec un tableau qui donne les distances..
J'ai beaucoup de mal, car mon uml de mon programme de base n'est plus cohérent, vu que à chaque fois je dois ajouter des "améliorations".
Et merci beaucoup de ton aide ou plus d'un m'aurait laisser me débrouiller tout seul.
Ouch !
Tu vas te faire trucider à tenir de pareils propos
Cocoa a des bindings et des propriétés partout, ce que tu dis est une hérésie .
Tu as lu le guide ?
En particulier ce qui concerne les collections ?
Tu pourrais t'inspirer de la manière dont Core Data modélise les données pour mieux visualiser comment concevoir tes classes, par contre je ne te conseille pas de l'utiliser tout de suite: tout ou presque semble passer par les liens et KVC/KVO.
Une Entité est une Classe, une Property un attribut (avec ses accesseurs), une fetched property un array ou un set d'objets liés à ton objet.. Tu ne dois pas avoir de donnée stockée dans deux endroits si ce n'est temporairement... Quand tu as mis tes idées "au propre" tu transposes dans ton application avec tes classes (plus faciles à manipuler que les entités).
(Et quand on arrivera aux principes de delegation, de MVC et d'abstraction et d'encapsulation, ça risque de se corser !)
Quant au KVC, ce n'est pas le moyen à privilégier pour accéder aux données surtout vu le fonctionnement du mécanisme. C'est juste un mécanisme, une fonctionnalité, qui peut dans certains cas être utiles selon ton architecture pour simplifier certains patterns pour lesquels tu ne peux pas faire autrement. Mais dans ce cas faut avoir conscience des conséquences et du fonctionnement du mécanisme. Mais bon pour ça faut déjà avoir connaissance des Design Patterns de base avant d'en arriver au KVC et au KVO. C'est un peu comme si tu disais que pour acheter une voiture, tu pouvais la payer en liquide. Avec
Rien ne vaut un bon bouquin pour t'enseigner les bases de l'Objective-C avec une orientation Objet. Tu galèreras bcp moins après. Car là il te manque clairement des bases en POO.
Mais bon, on peut pas devenir un grand maà®tre du jour au lendemain.
Enfait je croie que je me suis mal exprimé. Ce que je demande c'est ce que ça m'apporte de plus par rapport à ce que j'ai déjà .
Je suis d'accord que le code aura une meilleur conception. Mais en même temps, si ça fonctionne et que c'est encore "potable", vu que je suis encore novice en programmation, je peux pas tout savoir non plus. Et passer énormément de temps à comprendre de nouvelle notions, sans savoir ce que ça m'apporte en plus, je comprend vraiment pas.
Le plus gros problème à mon sens était les if/else de base. Après je suis d'accord que j'ai fait d'énorme bourde, que je viens de corriger encore aujourd'hui (par exemple afficher les valeurs dans le tableau avec un NSNumber).
Mon programme est on va dire le premier que je refait réellement tout seul, donc je pense que c'est normal qu'il y ai beaucoup de chose à redire.
Peut-être que je ne cherche pas assez.
Et le mon dernier problème était juste par rapport à la recherche, et les tableaux. En quoi utiliser le KVC me permettrait de modifier au niveau de ma conception dans mes tableaux. J'en aurai toujours 2 non ? un de base et un pour la recherche.
À moyen terme, le MVC permet d'avoir une architecture plus claire. ça réduit les bugs et la complexité.
Mais l'argument massue est que Cocoa est conçue dans l'esprit que les programmeurs respectent le MVC. Il est rendu difficile d'aller contre cette nature, alors autant s'y plier.
C'est pour cela qu'Ali insiste pour que tu respectes le MVC: toutes tes difficultés proviennent du fait que tu mélanges contrôleur et modèle et de l'absence de définition précise de ton modèle. T'es pas le seul, rassure-toi, mais il vaut mieux travailler son modèle dès le départ parce que s'il est bancal, tu vas reprendre ton HIM 30 fois.
Tu te dis je veux rapidement une maison vite fait, tu prends 3 planches et une boite de clous, tu les assembles rapidement même pas forcément bien droit, et puis bah ça marchotte, ça te fait un abri pour la nuit. Et puis dans une semaine, ta maison sera écroulée.
Tu peux passer un peu plus de temps à assembler tes planches bien droites pour t'assurer qu'elles ont une bonne jointure, puis tu fais ton isolation, et voilà . Ah oui mais tu as oublié de prévoir le passage de l'électricité et de la plomberie dans les murs... Bon c'est pas grave, tu va mettre des fils et des tuyaux apparents de partout, et des rallonges électriques de partout. Bon après tout ça marche, tu auras l'électricité et l'eau, donc tu peux te demander "qu'est ce que ça m'apporte de plus" ? Mais ça va être le fouilli de fils et de tuyaux, tu vas te prendre les pieds dedans un jour où l'autre, et je te parle pas de la sécurité et des risques d'électrocution ou d'incendie en cas de court-circuit. Et si tu n'as pas bien pensé tes fondations, tu risques d'avoir sous peu des fissures dans tes murs et avoir besoin de faire des travaux de partout pour rattraper les dégradations ou les oublis lors de la conception... ce qui va te faire du rafistolage de partout, et te coûter très cher, bien plus cher au total.
Tu peux aussi prendre le temps de bien faire les plans de ta maison, prévoir les fondations d'abord, puis bien structurer le tout, et t'assurer que tout a été pensé proprement au début. Faire des plans de câblage, vérifier que tout est cohérent, et tout. Puis construire ta maison étape par étape, sans mettre l'isolation et refermer tes murs avant d'avoir fait passer l'électricité et la plomberie, parce que tu auras pris le temps de pensé à la conception de ta maison plutôt que de te précimiter. Et du coup avec des fondations solides tu auras une maison solide qui ne risque pas de s'écrouler au bout de quelques mois avec des fissures partout.
Après, si tu te demandes toujours ce que ça t'apporterai de faire de l'architecture logicielle pour ton projet et de bien comprendre les bases et de bien penser ton programme plutôt que de le gaver de rustines et de patchs...
Mais je voulais pas m'admettre vaincu aussi facilement lol, car j'ai déjà beaucoup travaillé dessus. Et on va dire qu'il est presque finit quoi.
(mon programme fait d'autres tâches que la géoloc).
Et maintenant (en ce qui me concerne), j'ai l'impression que je doit refaire mon programme juste à cause d'une searchBar.
En effet, Ali, tu m'a aidé à résoudre tous mes autres problèmes (où j'ai mis bcp bcp de temps à comprendre que récupérer un seul tableau d'annotations était plus adéquate). j'ai plus de if/else que je doit répéter à chaque fois.
J'ai une classe pour créer les annotations, une pour créer le tableau d'annotations Restaurants qui me renvoie un tableau d'annotations.
Que je récupère dans mon RootViewController.
Ensuite j'utilise ce tableau pour créer mes annotations (avec la bonne manière).
Donc la, je me demande en quoi mon architecture ne convient pas.
Après je suis d'accord que pour récupérer la distance et afficher le tout dans la tableView, il y un problème.
Au pire des cas, j'enleve la searchBar pour le moment. Puis quand j'aurai une meilleure experience je pourrai m'y attaquer de nouveau.
Si je peux m'imisser dans cette discussion très fructueuse car j'ai un problème qui est proche de celui là je dirait
En fait j'ai un plan sur lequel je doit afficher des annotations prises dans un tableau. Ensuite grâce à un picker contenant touts les types on filtres ces annotations.
Voici mon code
....///
for (ACOPointOfInterest *poi in poisList)
{
NSMutableArray *poisPerType = (NSMutableArray *)[poisPerTypes objectForKey:poi.typePoi];
if (poisPerType == nil)
{
poisPerType = [NSMutableArray alloc] initWithCapacity:0] autorelease];<br /> [poisPerTypes setObject:poisPerType forKey:poi.typePoi];<br /> }<br /> <br /> [poisPerType addObject:poi];<br /> //[poisPerType addObjectsFromArray:[poi valueForKey:poi.typePoi;
}
DLog(@Pois per type : %@", poisPerTypes);
// Appel de la pickerView contenant tous les POIs.
if (pickerController == nil)
{
pickerController = [[ACOPickerViewController alloc] init];
pickerController.delegate = self;
[pickerController clearAllItems];
for (NSString *poiKey in [poisPerTypes allKeys])
{
[pickerController addItemWithText:[NSString stringWithFormat:@%@", [poisTypeStrings valueForKeyPath:[NSString stringWithFormat:@%@.title", poiKey]]] andValue:poiKey];
}
}
ET CEST LA OU MON BLOCAGE ARRIVE CAR CEST A PARTIR DE LA QUE JE VEUX AFFICHER TOUTES LES ANNOTATIONS : EN FAIT AVEC CETTE BOUCLE CA M'AFFICHE QUE LE DERNIER ELEMENT
for (int i = 0; i < [poisPerTypes count]; i++)
{
//[pickerController.delegate pickerViewController:pickerController didSelectValue:poisPerTypes allKeys] objectsAtIndexes:;
[pickerController.delegate pickerViewController:pickerController didSelectValue:poisPerTypes allKeys] objectAtIndex:i;
//DLog (@TEST = , poisPerTypes);
}
ET VOICI MON PICKER
.../////
- (void)pickerViewController:(ACOPickerViewController *)viewController didCancel:(id)selectedValue
{
}
- (void)pickerViewController:(ACOPickerViewController *)viewController didSelectValue:(NSString *)selectedPoiType
{
PXReleaseSafely(selectedOptionValue);
selectedOptionValue = [selectedPoiType retain];
DLog(@Poi type : %@", selectedPoiType);
if (displayedPois != nil)
{
[mapView removeAnnotations:displayedPois];
}
displayedPois = (NSArray *)[poisPerTypes objectForKey:selectedPoiType];
[mapView setDelegate:self];
[mapView addAnnotations:displayedPois];
DLog(@Pois = %@", displayedPois);
}
Voila merci beaucoup pour votre aide