Trier une Tableau avec un NSDictionary ?

karouselkarousel Membre
02:17 modifié dans Vos applications #1
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
«1

Réponses

  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #2
    Pourquoi tu as plusieurs fois les mêmes objets dans autant de structures ?
    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)
  • karouselkarousel Membre
    02:17 modifié #3
    J'ai autant d'objet, car enfait j'ai crée une UISearchBar. Et d'après le tuto que j'ai lu, il fallait faire plusieurs tableaux.
    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 :
    <br /> [variableAAfficher removeAllObjects];<br /> [variableAAfficher addObjectsFromArray:[sortedArray valueForKey:@&quot;nom&quot;]]; <br />
    


    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
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #4
    dans 1305127274:

    J'ai autant d'objet, car enfait j'ai crée une UISearchBar. Et d'après le tuto que j'ai lu, il fallait faire plusieurs tableaux.
    Et maintenant tout mon programme repose la dessus.
    Pourquoi, est-ce que c'est grave de recréer des tableaux, au niveau mémoire ?
    J'ai jamais dit que c'était "grave" de créer des tableau, encore moins niveau mémoire.
    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 ?)
  • karouselkarousel Membre
    02:17 modifié #5
    Ahh okay, enfait j'ai des noms de lieu, et je calcule la distance par rapport à  l'utilisateur.
    Et je le classe par ordre de plus petit au plus grand
    voici mon code :
    <br />/Lorsque l&#039;on recherche un mot<br />- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText<br />{<br />[variableAAfficher removeAllObjects];//Supprime les ancienes recherches<br />if([searchText isEqualToString:@&quot;&quot;]||searchText==nil){<br />[maTableViewRecherche reloadData];<br />return;<br />}<br />NSInteger counter = 0;<br />for(NSString *name in variableTableau)<br />{<br />NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];<br />NSRange r = [name rangeOfString:searchText options:NSCaseInsensitiveSearch];<br />if(r.location != NSNotFound)<br />{<br />[variableAAfficher addObject:name];<br />}<br />counter++;<br />[pool release];<br />}<br /> <br /> <br /> <br />//Crée un tableau pour verifier quel lieu est le plus prés<br />NSMutableArray *triageTableau=[[NSMutableArray alloc] init];<br />for(int j=0;j&lt;[variableAAfficher count];j++) {<br />float longit=0;<br />float lat=0;<br />float distance=0;<br /> <br />NSString*resultat=[variableAAfficher objectAtIndex:j];<br /> <br />//Longitude et latitude de chaque Annotations (ici resort longit et lat pour toutes mes variables)<br />{...}<br /> <br />//Distance utilisateur/annotations<br />distance=acos(sin(maMapView.userLocation.location.coordinate.latitude)*sin(lat)+cos(maMapView.userLocation.location.coordinate.latitude)*cos(lat)*cos(longit-maMapView.userLocation.location.coordinate.longitude))*6371;<br /> <br /> <br />//Crée un dictionnaire avec les lieux et les distances<br />[triageTableau insertObject:[NSDictionary dictionaryWithObjectsAndKeys:[variableAAfficher objectAtIndex:j], @&quot;lieux&quot;,[NSNumber numberWithFloat:distance], @&quot;distance&quot;,nil] atIndex:j];<br />}<br /> <br /> <br />//Je trie mon dico par rapport aux distances<br />NSSortDescriptor *sortDescriptor;<br />sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@&quot;distance&quot;&nbsp; ascending:YES] autorelease];<br />NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];<br />NSArray *sortedArray = [triageTableau sortedArrayUsingDescriptors:sortDescriptors];<br /> <br /> <br />//Tableau en enlevant les distances (une fois supprimé, et on ajoute a variableAAfficher)<br />[variableAAfficher removeAllObjects];<br />[variableAAfficher addObjectsFromArray:[sortedArray valueForKey:@&quot;lieux&quot;]];&nbsp;  <br />[triageTableau release];<br /> <br />[maTableViewRecherche reloadData];<br />}<br />
    



    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
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #6
    Wah!
    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.
  • karouselkarousel Membre
    02:17 modifié #7
    Comment sa pour la recherche ? mon NSSortDescriptor n'est pas adéquate ?



    Ben donc je devrai créer une NSDictionnary avec mes valeurs et noms, et ensuite je vais chercher dedans comment ?
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #8
    J'avais pas vu plus bas ton sortDescriptor sur la clé "distance".
    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.
  • karouselkarousel Membre
    02:17 modifié #9
    Merci pour votre aide.

    Oui j'ai déjà  modifié ma ma façon de calculer la distance (c'est vrai que il y a plus simple):
    <br /> distance = sqrtf((maMapView.userLocation.location.coordinate.latitude - lat)*(maMapView.userLocation.location.coordinate.latitude - lat) + (maMapView.userLocation.location.coordinate.longitude - longit) *(maMapView.userLocation.location.coordinate.longitude - longit));<br />
    


    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 ?
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #10
    Pour moi tu n'as uniquement besoin que de ce code là , et rien d'autre (pas de boucle for, etc) pour avoir ton tableau de tous les éléments et ton tableau "filtré pour correspondre à  la recherche et trié par distance" :
    @interface POI : NSObject<br />@property(retain) CLLocation* position;<br />@property(retain) NSString* name;<br />...<br />@end<br /><br />@interface MonViewController : UIViewController<br />@property(retain) NSArray* allPOIs;<br />@property(retain) NSArray* filteredPOIsByDistance;<br />@end
    
    NSArray* filteredPOIs = [allPOIs filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@&quot;SELF.name CONTAINS %@&quot;,searchText];<br />self.filteredPOIsByDistance = [filteredPOIs sortedArrayUsingComparator:^(id obj1, id obj2) {<br />&nbsp; POI* poi1 = (POI*)obj1; POI* poi2 = (POI*)obj2;<br />&nbsp; CLLocationDistance d1 = [poi1 distanceFromLocation:userLocation];<br />&nbsp; CLLocationDistance d2 = [poi2 distanceFromLocation:userLocation];<br />&nbsp; return (d1&lt;d2) ? NSOrderedAscending : (d1&gt;d2) ? NSOrderedDescending : NSOrderedSame;<br />}];
    
    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...
  • karouselkarousel Membre
    02:17 modifié #11
    Merci de m'aider, mais je crois que je suis un cas désespéré lol...

    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...
  • AliGatorAliGator Membre, Modérateur
    mai 2011 modifié #12
    dans 1305215941:

    Merci de m'aider, mais je crois que je suis un cas désespéré lol...

    Le truc c'est que j'ai réalisé un programme, et maintenant je pas changer une partie apres sa fera buger le reste.
    Ca c'est typique d'une mauvaise conception au départ. Si en plus tu n'as pas respecté le MVC (pattern Model/View/Controller) dans ta conception t'es bon pour tout revisiter et réviser ta conception...

    dans 1305215941:
    En gros, j'ai une une classe annotation pour definir mes annotations.
    Une classe restaurant qui contient les noms, coordonnées etc...
    Pourquoi ne pas simplement faire en sorte que ta classe restaurant se conforme au protocole MKAnnotation ?

    dans 1305215941:
    Une UIView RootViewController
    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...
    dans 1305215941:
    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.
    Si Restaurant se conformait direct au protocole ça serait pas plus simple?

    dans 1305215941:
    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.
    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

    dans 1305215941:
    Mais dans ma classe RootViewController, je ne peut pas récupérer chaque POI, puisque ça me renvoi un tableau.
    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
    dans 1305215941:
    Donc la méthode CLL location ne peut pas s'initialiser, si ?
    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!


    dans 1305215941:
    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.
    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
  • karouselkarousel Membre
    02:17 modifié #13
    Comment faire en sorte que ma classe restaurant se conforme au protocole MKAnnotation ?
    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.
  • AliGatorAliGator Membre, Modérateur
    mai 2011 modifié #14
    dans 1305227235:

    Comment faire en sorte que ma classe restaurant se conforme au protocole MKAnnotation ?
    J'utilise la classe annotation pour initialiser mes "restaurants". Dans ma classe annotation, c'est du style monAnnotation*Resto1=....[...]
    Comment ça, si Restaurant se conformait direct au protocole ? je ferait un protocole dans ma classe annotation ?
    Heu MKAnnotation est déjà  un protocole ! (A moins que tu confondes avec MKAnnotationView, tu as déjà  confondu View et ViewController... mais bon si tu n'utilises pas les bons termes ça va être dur pour moi de t'aider donc j'espère que tu parlais bien de MKAnnotations !)

    dans 1305227235:
    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 .....
    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
    Restaurant* resto = [listeRestaurants objectAtIndex: indexPath.row];<br />cell.textLabel.text = resto.name;
    
    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 !
    dans 1305227235:
    Le truc c'est que je vois pas comment on peut trier un tableau en fonction du type de valeurs à  l'intérieur.
    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à .

    dans 1305227235:
    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 ?
    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)

    dans 1305227235:
    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.
    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)
  • karouselkarousel Membre
    mai 2011 modifié #15
    Donc ma classe Restaurants est okay (car l'initialisation se fait avec les MKannotations), et elle me renvoie bien un tableau d'annotations.

    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.

    <br /><br /> MonAnnotation*monAnnotationRestaurant=[tableauRestaurant objectAtIndex:5]; <br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;titre : %@&quot;, monAnnotationRestaurant.title); <br /><br />
    


    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).
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #16
    Je capte pas tous tes restaurants n'ont pas d'annotation associée ?! C'est vraiment pas clair ton truc
  • karouselkarousel Membre
    mai 2011 modifié #17
    Bon si.
    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) :
    <br /><br /> MonAnnotation * restoU1=[[MonAnnotation alloc] init];<br />&nbsp; &nbsp; restoU1.title=@&quot;Resto test&quot;;<br />&nbsp; &nbsp; restoU1.subtitle=@&quot;9 avenue de la forêt de Haye&quot;;<br />&nbsp; &nbsp; restoU1.longitude=[NSNumber numberWithDouble:6.0+0.14182];<br />&nbsp; &nbsp; restoU1.latitude=[NSNumber numberWithDouble:48.0+0.65084];<br />&nbsp; &nbsp; restoU1.identifiant=[NSNumber numberWithInt:1]; <br />&nbsp; &nbsp; [arrayOfAnnotations addObject:restoU1];<br />&nbsp; &nbsp; [restoU1 release];<br /><br />
    


    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 :
    <br /><br />tableauAnnotations=[[NSMutableArray alloc] initWithArray:[annotationRestaurant arrayOfAnnotations]];<br /><br />
    




    Et après mon problème c'est pour le lire, je peux ressortir chaque valeur de mon tableau, mais avec une boucle for :
    <br /><br />&nbsp; &nbsp; &nbsp; &nbsp; int i;<br />&nbsp; &nbsp; &nbsp; &nbsp; for (i=0; i&lt;[tableauAnnotations count]; i++) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonAnnotation*monAnnotation=[tableauAnnotations objectAtIndex:i]; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;titre de mes Annotations : %@&quot;, monAnnotation.title);<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br /><br />
    


    Je peux garder ce bout de programme pour lire le tableau, mais ça me fait de nouveau plein de boucles.
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #18
    Mais pourquoi tu veux encore récupérer un tableau ne contenant que la liste de tes monAnnotation.title ? Tu en as besoin pour quoi de ce tableau qui ne contient que les titres ?
    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).
  • karouselkarousel Membre
    mai 2011 modifié #19
    Bonjour,
    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
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #20
    dans 1305529734:

    Bonjour,
    Ben je veut extraire car j'en ai besoin pour afficher le titre dans mon tableau (pour la recherche).
    Bah non, aucunement.
    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...

    dans 1305529734:
    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
    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.
  • karouselkarousel Membre
    mai 2011 modifié #21
    Si j'ai compris ce que l'on peut faire avec cell.textLabel...
    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 :
    <br /><br />cell.textLabel.text = [[variableAAfficher valueForKey:@&quot;lieux&quot;] objectAtIndex:indexPath.row];<br />&nbsp; &nbsp; <br />cell.detailTextLabel.text= [@&quot;Distance en km (à  vol d&#039;oiseau) : &quot; stringByAppendingString:[NSString stringWithFormat:@&quot;%@&quot;,[[variableAAfficher valueForKey:@&quot;distance&quot;] objectAtIndex:indexPath.row]]]; <br />&nbsp; &nbsp; &nbsp;  <br />[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];<br />tableView.accessibilityLabel=cell.textLabel.text;<br /><br />
    



    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 :
    <br /><br />//Crée un tableau pour verifier quel lieu est le plus prés<br />&nbsp; &nbsp; NSMutableArray *triageTableau=[[NSMutableArray alloc] init];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; float distance;<br />&nbsp; &nbsp;  for (int i=0; i&lt;[tableauAnnotations count]; i++) {<br />&nbsp; &nbsp; &nbsp; &nbsp;  MonAnnotation*monAnnotation=[tableauAnnotations objectAtIndex:i]; <br /><br />&nbsp; &nbsp; for(int j=0;j&lt;[variableAAfficher count];j++) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Tableau qui est affiché<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSString*resultat=[variableAAfficher objectAtIndex:j];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; if ([resultat isEqualToString:monAnnotation.title]) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Distance utilisateur/annotations<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distance = sqrtf((maMapView.userLocation.location.coordinate.latitude - [monAnnotation.latitude floatValue])*(maMapView.userLocation.location.coordinate.latitude - [monAnnotation.latitude floatValue]) + (maMapView.userLocation.location.coordinate.longitude - [monAnnotation.longitude floatValue]) *(maMapView.userLocation.location.coordinate.longitude - [monAnnotation.longitude floatValue]))*100; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Crée un dictionnaire avec les lieux et les distances<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [triageTableau insertObject:[NSDictionary dictionaryWithObjectsAndKeys:[variableAAfficher objectAtIndex:j], @&quot;lieux&quot;,[NSNumber numberWithFloat:distance], @&quot;distance&quot;,nil] atIndex:j];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp;  }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //Je trie mon dico par rapport aux distances<br />&nbsp; &nbsp; NSSortDescriptor *sortDescriptor;<br />&nbsp; &nbsp; sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@&quot;distance&quot;&nbsp; ascending:YES] autorelease];<br />&nbsp; &nbsp; NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];<br />&nbsp; &nbsp; NSArray *sortedArray = [triageTableau sortedArrayUsingDescriptors:sortDescriptors];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; //Tableau en enlevant les distances (une fois supprimé, et on ajoute a variableAAfficher<br />&nbsp; &nbsp; [variableAAfficher removeAllObjects];<br />&nbsp; &nbsp; [variableAAfficher addObjectsFromArray:sortedArray]; <br /><br />
    


    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).

  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #22
    dans 1305550758:

    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.
    Bah oui, bien sûr, c'est comme ça qu'il faut faire. Mais en quoi tu as besoin ce cet array de recherche soit un array ne contenant que les noms ? C'est juste une version "filtrée" de ton array "de base" qui lui contient tout, donc si ton array de base contient une liste de restaurants (de la classe Restaurant, contenant plein d'infos comme le nom, la CLLocation, le téléphone du resto ou que sais-je encore), bah ton array "de recherche" sera qu'une version filtrée donc un autre array contenant une liste de restaurants, qui ne sera qu'un sous-ensemble du tableau "de base", ne contenant que les objets Restaurant correspondant au critère de recherche.

    dans 1305550758:
    Mon code pour la tableView :
    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" !!
    • Pourquoi utiliser le KVC qui va te créer en interne des tableau intermédiaires alors que tu n'en as là  encore pas besoin...
      [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".
    • Pourquoi ne pas rester LOGIQUE (j'ai l'impression que c'est pas ton fort, faut que tu comprennes les bases de l'architecture logicielle plutôt que de faire de la bidouille) et récupérer ton objet Restaurant correspondant à  la cellule à  afficher et ENSUITE demander à  cet unique objet restaurant " puisque forcément pour la cellule que tu es en train de remplir au moment de l'appel de ce code, y'a que ce restaurant qui t'intéresse " uniquement ses propriétés ?
    • Donc [tt]Restaurant* resto = [variableAAfficher objectAtIndex:indexPath.row];[/tt] comme ça tu ne dérives pas un tableau avec le KVC à  partir de ton tableau complet (sinon bonjour les perfs si ton tableau contient genre 2000 restos, la belle aberration !), mais au contraire tu ne récupères que le resto qui t'intéresse, celui qui correspond à  la cellule en cours de configuration (pourquoi s'embêter avec le reste ??). Et ensuite, tu peux faire tout simplement [tt]cell.textLabel.text = resto.lieux;[/tt] et [tt]cell.detailTextLabel.text = resto.distance;[/tt] et c'est tout. 100x plus logique, 100x plus efficace.
    • Et je passe toutes les autres aberrations comme ne pas mutualiser le code commun genre le accessoryType, ou changer l'accessibilityLabel de la tableView (donc de l'ensemble de ta liste) à  chaque fois que la tableView demande une cellule (donc uniquement un élément de ta liste) donc au final l'accessibilityLabel de ta tableView prendra la valeur du texte... d'une de tes cellules de ta table, on sait pas trop laquelle (ça dépend dans quel sens l'utilisateur scroll entre autres... loin d'être logique)
    • Et je passe également sur l'utilisation étrange du couple stringByAppendingString + stringWithFormat au lieu de tout mettre d'une seule traite... et encore plus sur le fait que tu utilises %@ pour afficher la distance, sans la formatter (au lieu de récupérer le NSNumber correspondant à  la distance " enfin j'espère que c'est un NSNumber et pas autre chose genre NSString " et d'utiliser un NSNumberFormatter pour l'afficher proprement, ou même beaucoup plus simplement d'utiliser un format type "%.2f" et de passer non pas le NSNumber directement bien sûr en argument, mais sa floatValue... Encore une aberration de plus que je ne comprends pas
    • Et je vois que tu calcules encore la distance via une boucle for, au lieu de la calculer uniquement à  l'affichage ou au tri ou là  où tu en as besoin (alors qu'en plus je t'ai donné toutes les billes et tout le code pour ça dans les posts précédents



    dans 1305550758:
    La tout est nikel, sauf que je ne peut pas tronquer ma distance puisque qu'elle est en format %@ et non %f.
    Bah oui justement, pourquoi tu utilises %@ et passes directement le NSNumber encapsulant la distance justement ? Pourquoi ne pas utiliser %f et la floatValue ?


    dans 1305550758:

    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).
    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)
  • karouselkarousel Membre
    mai 2011 modifié #23
    OKay, je sais qu'il me reste beaucoup à  faire.
    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.
    <br /><br />NSArray* filteredPOIs = [allPOIs filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@&quot;SELF.name CONTAINS %@&quot;,searchText];<br />self.filteredPOIsByDistance = [filteredPOIs sortedArrayUsingComparator:^(id obj1, id obj2) {<br />&nbsp; POI* poi1 = (POI*)obj1; POI* poi2 = (POI*)obj2;<br />&nbsp; CLLocationDistance d1 = [poi1 distanceFromLocation:userLocation];<br />&nbsp; CLLocationDistance d2 = [poi2 distanceFromLocation:userLocation];<br />&nbsp; return (d1&lt;d2) ? NSOrderedAscending : (d1&gt;d2) ? NSOrderedDescending : NSOrderedSame;<br /><br />
    

    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.
  • laudemalaudema Membre
    02:17 modifié #24
    dans 1305617911:


    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.


    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).
  • AliGatorAliGator Membre, Modérateur
    mai 2011 modifié #25
    Arrête tout et prend un bon bouquin qui va t'expliquer les bases de la programmation, et en particulier la programmation objet. Parce que là  déjà  faire de l'Objective-C et du Cocoa ça nécessite de suivre des tutos tu peux pas te plonger dedans directement aveuglément, mais en plus si tu n'as aucune notion de POO et que tu sors des trucs comme "je vois pas ce que déclarer une @property pourrait m'apporter" alors que c'est un peu LA BASE de la POO, c'est que tu n'as pas encore compris les concepts de base de la POO.
    (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.
  • karouselkarousel Membre
    02:17 modifié #26
    Oui justement, j'ai déjà  lu beaucoup à  propos d'objective C. le MVC, je comprend, mais entre ce qui à  écrit dans un livre et la réalité, ça change un peu.
    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.
  • CéroceCéroce Membre, Modérateur
    mai 2011 modifié #27
    dans 1305626839:

    Ce que je demande c'est ce que ça m'apporte de plus par rapport à  ce que j'ai déjà .


    À 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.
  • AliGatorAliGator Membre, Modérateur
    02:17 modifié #28
    Oui comme je le disais dans un autre post, c'est comme si tu construisais une maison sans t'assurer que les fondations sont stables. C'est l'histoire des trois petits cochons (révisons nos classiques :D)

    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...
  • karouselkarousel Membre
    02:17 modifié #29
    Ah okay, oui je comprends mieux maintenant.

    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.
  • hedihedi Membre
    02:17 modifié #30
    Bonjour
    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
  • DrakenDraken Membre
    02:17 modifié #31
    Tu sais, ton code serait plus lisible en employant la balise code, le symbole "#". Il est placé au dessus de l'icône d'un type levant le pouce et celle d'un mec atteint de tremblote.

    Ceci est du code<br />
    


Connectez-vous ou Inscrivez-vous pour répondre.