NSArray problème de filtre [résolu]

wiskywisky Membre
août 2005 modifié dans API AppKit #1
Au lancement de mon appli j'ai 3 NSArray qui sont initialisé.

Array1 contient les données chargé à  partir d'un fichier
Array2 contient le resultat du premier filtre
Array3 contient le resultat du deuxieme filtre

au début [tt]Array1 = Array2 = Array3[/tt] tout vas bien! tout marche.

Ensuite j'applique le premier filtre. Array2 reçoit les objet de Array1 qui coresponde aux critères. là  tout va bien

ensuite j'applique encore un filtre sur Array2 qui me donne Array3. là  tout va bien.

mais quand je retire le deuxième filtre je fait [tt]Array3 = Array2[/tt] et là  plus rien! tout à  disparut. Je suis obligé de ré-appliquer le premier filtre pour retrouver les données. Le code du deuxième filtre est bon car je peut l'appliquer sans avoir appliquer le premier.

Voici le code du premier filtre (quand il y en a un)
NSMutableArray *contents = [[NSMutableArray alloc] initWithArray:[dico objectForKey:@&quot;contents&quot;]];<br />		NSEnumerator *enumerator, *e;<br />		NSString *fnString;<br />		id object,o;<br />		<br />		e = [Array1 objectEnumerator];<br />		<br />		[subset release];<br />		subset = [[NSMutableArray alloc] init];<br />		<br />		while ( o = [e nextObject] ) {<br />			fnString = [o objectForKey:@&quot;IndexUniq&quot;];<br />			enumerator = [contents objectEnumerator];<br />			while(object = [enumerator nextObject])<br />				if ( [fnString isEqualToString:object])<br />					[subset addObject:o];<br />		}<br />		Array2 = subset;<br />		//[saveActiveSet release];<br />		Array3 = Array2;<br />		[TableView reloadData];



La TableView à  pour datasource Array3.

J'ai loupé un truc ou je devien fou ?  :crackboom:- :crackboom:- :crackboom:-

Réponses

  • Eddy58Eddy58 Membre
    août 2005 modifié #2
    Qu'est-ce que donne un log après avoir modifié le pointeur d'Array2 ? ???
    [tt]
    Array2 = subset;
    NSLog(@Array2:%@",Array2);
    [/tt]

    Avant de releaser "subset", il vaut mieux tester son existence pour éviter un plantage si son retain count est déjà  à  zéro.
    [tt]
    if (subset!=nil)
    {
          [subset release];
    }
    [/tt]
    Ou alors, tu peux supprimer le test et releaser "subset" dès que tu as fini avec, c'est plus sur.
  • wiskywisky Membre
    17:54 modifié #3
    c'est en effet [tt][subset release];[/tt] qui fait tou planté et en plus effaçait les données. C'est un méli mélo de pointeur et le moindre problème fait tout planté.

    Maintenant ça marche <3
  • août 2005 modifié #4
    Petit conseil: quand tu dois faire des filtrages, il vaut mieux passer par des NSSet. Un NSSet est un ensemble au sens math du terme, il est très pratique car il contient des méthodes intéressantes comme par exemple de pouvoir comparer deux sets, et ne retenir que les éléments communs. Ce qui est justement intéressants pour les filtrages.

    Dans ton cas, si j'ai bien compris, tes données sont stockées dans un tableau Array1, et il te faut les éléments dont la valeur à  la clé @IndexUniq se retrouvent dans le tableau contents :

    [tt]NSArray* indexUniqs = [Array1 valueForKey:@IndexUniq]; //renvoie un tableau qui contient toutes les valeurs pour la clé @IndexUniq des objets contenus dans Array1
    NSMutableSet* set = [NSMutableSet setWithArray:indexUniqs];// on mets tout dans un set
    NSSet* contents = [NSSet setWithArray:[dico objectForKey:@content]]; // on crée un set qui contient les éléments de contents.

    [set intersectsSet:contents]; //on demande à  set de ne garder que les éléments communs entre son contenu et celui de contents. le tri est fait.

    //Et maintenant, il faut une petite boucle pour récupérer les objets de Array1 eux même, plutôt que leur indexUniq.
    NSMutableArray* items = [NSMutableArray array];
    NSEnumerator* e = [set objectEnumerator];
    id obj;
    while (obj = [e nextObject]) [items addObject:[Array1 objectAtIndex:[indexUniqs indexObject:obj]];[/tt]

    Le gros avantages de cette méthode est que si tu veux rajouter des critères de tris, il ne faut qu'une ligne par critère, plutôt que de multiplier les boucles. En virant les commentaires, tu verras que ce code est très compact ;)

    EDIT: le seul 'inconvénient' de cette méthode (tout dépend de ta manière de travailler) est que les éléments dans items ne seront pas forcément dans le même ordre que dans Array1.
  • wiskywisky Membre
    17:54 modifié #5
    Merci renaud ;)
    C'est très intéressant. C'est exactement ce que je cherchait à  faire.
    Je modiffirait demain.
Connectez-vous ou Inscrivez-vous pour répondre.