(Réglé) Problème pour supprimer un objet sérialisable

Ben77650Ben77650 Membre
juillet 2014 modifié dans API UIKit #1

Bonjour,


 


J'ai un souci pour supprimer un objet sérialisable, 1 fois sur 2 il me dit que l'index est en dehors du tableau, c'est pas faute de faire des conditions pour vérifier que le tableau est vide ou non, mais il me sors des erreurs de ce type la:


 



Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM removeObjectAtIndex:]: index 3944917551 beyond bounds [0 .. 2]'


*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM removeObjectAtIndex:]: index 3937150031 beyond bounds [0 .. 0]'


 



 


Déjà  j'aimerais bien savoir d'où sort ce chiffre de malade de 3 milliards, j'avoue ne pas comprendre


 


Voila mon code:


 


Classe de serialisation:



-(id)init{
    self = [super init];
    if( self )
    {
        objects = [NSMutableArray new];
         NSString* documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
         fichier = [documentPath stringByAppendingPathComponent:@objets.archive];
         id serializeObjet = [NSKeyedUnarchiver unarchiveObjectWithFile:fichier];
         if(serializeObjet==nil){
         objects = [NSMutableArray new];
         }
         else{
         objects = serializeObjet;
         }

    }
    return self;
}

-(void) save:(NSMutableArray*) tab
{
    [objects addObject:tab];
    [NSKeyedArchiver archiveRootObject:objects toFile:fichier];
    
}
-(void) remove:(NSMutableArray*) tab;
{
    int indexTab;
    if([objects count]>0 && [tab count]>0)
    {
    NSSet* set1=[NSSet setWithArray:tab];
    NSSet* set2=[NSSet setWithArray:objects];
    for(int i=0;i<[objects count];i++){
        if([set1 isEqualToSet:set2])
            {
                NSLog(@Egal);
                indexTab = i;
            }
        else
            {
                NSLog(@Pas égal);
            }
    }
    [objects removeObjectAtIndex:indexTab];
    [NSKeyedArchiver archiveRootObject:objects toFile:fichier];
    }
}

-(NSMutableArray*) getAll
{
    for(int i=0;i<[objects count];i++){
        [objects objectAtIndex:i];
    }
    return objects;
}

Utilisation du code (Endroit 1):



-(void) favorite
{
    
    if(_boolFavori==0)
    {
        SerializableRepository* ser = [[SerializableRepository alloc]init];
        [ser save:_offreDetail];
        NSLog(@ser count %d, [[ser getAll]count]);
        
        UIAlertView *alertfavori = [[UIAlertView alloc] initWithTitle:@Favori
                                                    message:@L'annonce a bien été ajoutée aux favoris.
                                                   delegate:nil
                                          cancelButtonTitle:@OK
                                          otherButtonTitles:nil];
        [alertfavori show];
        
    
        [_favori setImage:[UIImage imageNamed:@retirer_favori.png]forState:UIControlStateNormal];
        [_favori addTarget:self action:@selector(favori) forControlEvents:UIControlEventTouchUpInside];
        [_scroll addSubview:_favori];
        _boolFavori = 1;
    }
    else
    {
        SerializableRepository* ser = [[SerializableRepository alloc]init];
        if([[ser getAll]count]>0)
        {
        [ser remove:_offreDetail];
        }
        
        UIAlertView *alertfavori = [[UIAlertView alloc] initWithTitle:@Favori
                                                              message:@L'annonce a bien été retirée des favoris.
                                                             delegate:nil
                                                    cancelButtonTitle:@OK
                                                    otherButtonTitles:nil];
        [alertfavori show];
        
        [_favori setImage:[UIImage imageNamed:@ajouter_favori.png]forState:UIControlStateNormal];
        [_favori addTarget:self action:@selector(favori) forControlEvents:UIControlEventTouchUpInside];
        [_scroll addSubview:_favori];
        _boolFavori =0;
    }
}

Utilisation du code (Endroit 2):



- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(editingStyle == UITableViewCellEditingStyleDelete)
    {
        SerializableRepository* ser = [[SerializableRepository alloc]init];
        [ser remove:_liste];
        
        [_liste removeObjectAtIndex:indexPath.row];
        //[listOffer deleteRowsAtIndexPaths:@[;indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [listOffer reloadData];
        
        if([_liste count] == 0)
        {
            listOffer.tableFooterView.hidden = YES;
            
            loadingView = [[UIView alloc] initWithFrame:CGRectMake(75, 200, 170, 100)];
            loadingView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
            loadingView.clipsToBounds = YES;
            loadingView.layer.cornerRadius = 10.0;
            
            
            loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(32.5, 40, 140, 22)];
            loadingLabel.backgroundColor = [UIColor clearColor];
            loadingLabel.textColor = [UIColor whiteColor];
            loadingLabel.adjustsFontSizeToFitWidth = YES;
            loadingLabel.text = @Aucun favori.;
            loadingLabel.lineBreakMode = NSLineBreakByWordWrapping;
            loadingLabel.numberOfLines=0;
            loadingLabel.textAlignment = NSTextAlignmentCenter;
            [loadingLabel sizeToFit];
            [loadingView addSubview:loadingLabel];
            [self.view addSubview:loadingView];
        }
    }
}

A noter qu'il me pose problème quasiment tout le temps dans l'endroit 1, et parfois dans l'endroit 2.


 


Merci à  ceux qui sauront m'aider


Réponses

  • Et un [objects removeObject:tab]? C'est simple, d'après la doc c'est safe et ça supprime toutes les occurrences (on ne sait jamais), ça évite de faire des boucles étranges et de jouer avec des index plus que douteux. 


  • Afin de t'expliquer mon objet Serializable est un tableau contenant lui même des tableaux d'où l'intérêt de l'index ;)


     


    Et le souci avec [objects removeObject: tab] c'est que ça me supprime jamais mon objet, que ça soit à  l'endroit 1 ou l'endroit 2


  • Exemple de ce que contient mon objet sérializable:


     



    (


            (


            "Le Tr\U00f4ne de fer - Livre 1",


            "2014/06/25/2d61462e61.jpg",


            "25-06-2014",


            4,


            "Paris, France",


            "Livres/Magazines",


            77160,


            Ben,


            "Apr\U00e8s avoir tu\U00e9 le monarque d\U00e9ment Aerys II Targaryen, Robert Baratheon est devenu le nouveau souverain du royaume des Sept Couronnes. Tandis qu'en son domaine de Winterfell, son fid\U00e8le ami le duc Eddard Stark rend paisiblement la justice. Mais un jour, le roi Robert lui rend visite, porteur de sombres nouvelles : le tr\U00f4ne est en p\U00e9ril. Stark, qui s'est toujours tenu \U00e9loign\U00e9 des affaires du pouvoir, doit alors abandonner les terres du Nord pour rejoindre la cour et ses intrigues. L'heure est grave, d'autant qu'au-del\U00e0 du mur qui prot\U00e8ge le royaume depuis des si\U00e8cles, d'\U00e9tranges cr\U00e9atures r\U00f4dent...


    \n


    \n


    \nTr\U00e8s bon \U00e9tat


    \nCause de la vente: Achat de l'int\U00e9grale 1",


            1843,


            "ben@gmail.com",


            0,


            1,


            N,


            0100000000,


                    (


            )


        ),


            (


            "Takedown Red Sabre (Steam Version",


            "2014/06/24/mt24p9g36z.jpg",


            "24-06-2014",


            1,


            "Paris, France",


            "Jeux vid\U00e9o",


            75013,


            Renault,


            "Je vends ce jeu car lors de l'achat j'en ai obtenu 2 copies",


            1832,


            "mail@mail.com",


            0,


            0,


            N,


            0836656565,


                    (


            )


        )


    )


     


  • Non bah plus je lis ce que tu fais moins je comprends...


     


    Je vois pas pourquoi si set1 n'est pas égales a set2 à  l'index 0 il le serait plus à  l'index 12 ou 14.


     


    Je vois pas pourquoi si tu transforme ton "tab" en set il serait égal en quoi que ce soit à  "objects" transformé lui aussi en set sachant que objects contient tab et que j'imagine que tab ne se contient pas lui même. 


     


    Je vois pas pourquoi si tu ajoutes un tableau et que tu essais de supprimer un tableau identique la méthode que je te donne ne marche pas. Sachant que tu essais quand même un moment donnée de comparer c'est deux tableau une fois transformé en set. 


     


    Je vois pas comment tu sais qu'a l'index 15 de ton tableau tu as un nom et à  l'index 18 un titre de film. 


     


    Bref je penses que tu devrais plus souvent arrêter de coder et réfléchir à  ce que tu dois faire. Par exemple la fonction que je t'ai passé prend un objet en entrer et le supprime dans un MutableArray donc ton paragraphe expliquant que c'est un tableau contenant des tableau et que donc il faut un index, je vois en quoi cela se justifie après, que ce que tu fais ne convient pas à  cette méthode ça je veux bien le croire mais vu de l'extérieur ça ne me semble pas normal.


  • L'histoire des sets est un moyen que j'ai trouvé pour comparer 2 tableaux, et cela sans prendre en compte l'ordre des éléments du tableaux. Cf ici


     


    Je vois pas non plus pourquoi ta méthode ne marche pas, mais c'est un fait, l'objet est toujours présent.


     


    Au niveau des index, c'est généralisé tous les index contiennent à  chaque fois le "type" d'informations souhaitée.


     


    Arrêter de coder et réfléchir ? J'ai passé 3 jours à  réfléchir sans coder une seule ligne, et autant te dire que ça plait pas forcément à  mon boss, qui se moque doucement de moi quand il voit que je cherche pendant plusieurs heures, et que je ne produit rien, ce qui l'intéresse lui c'est ce qui est produit.


  • Bon ok alors du coup ce que tu me dis c'est que ton tableau inclue dans "objects" a un ordre aléatoire, comment tu fais pour récupérer des données dans un objet que tu ne connais pas? 


     


    Ensuite je vois pas comment ta fonction marche au pire ça : 



    -(void) remove:(NSMutableArray*) tab;
    {
    int indexTab;
    if([objects count]>0 && [tab count]>0)
    {
    NSSet* set1=[NSSet setWithArray:tab];

    for(int i=0;i<[objects count];i++){
    NSSet* set2=[NSSet setWithArray:[objects objectAtIndex:i]];
    if([set1 isEqualToSet:set2])
    {
    NSLog(@Egal);
    indexTab = i;
    }
    else
    {
    NSLog(@Pas égal);
    }
    }
    [objects removeObjectAtIndex:indexTab];
    [NSKeyedArchiver archiveRootObject:objects toFile:fichier];
    }
    }

    Je verrais bien quelque chose mais ton code je vois pas comment il fait pour comparer les tableau de plus la on voit mieux l'utilité de la boucle for. 


    Je sais que je te rabats les oreilles avec mais pour moi dans ce genre de cas si tu ne veux pas faire de model de données ce qui pour moi est un tort mais bon pourquoi pas au moins utilise des dictionnaire c'est mieux rangé et on se fou de l'ordre ça se compare plus facilement et pour le relire c'est que du bonheur.


  • Mon tableau inclus dans objects a pas un ordre aléatoire, il m'affiche toujours tout dans le même ordre, mais on est jamais trop prudent d'où le fait que j'utilise un NSSet


     


    Bon ton code a l'air de fonctionner sans souci alors je vais prendre.


     


     


    Après c'est juste une question de préférence, je me sens plus à  l'aise dans l'utilisation d'un tableau plutôt que d'un dictionnaire, et en plus faudrait que je repasse tous mes tableaux en dictionnaire, ça prendrait pas mal de temps


  • Ah oui c'est sur que pour relire self.nameLabel.text = [objects objectAtIndex:12]; c'est super ça se lit bien en plus.


    Un jour le dev du web service rajoute un champ dans la fiche personnage et il l'ajoute à  l'index 1 le fourbe et du coup dans ton nom tu te retrouves avec le titre d'une bande dessiné ou le nom de son chien. Pire l'anciens index 11 était son age en NSNumber et la tu te retrouve avec un jolie plantage. C'est pas une question de préférence on fait pas forcement les choses parce qu'on aime pas faire autrement mais parce qu'on sait que c'est une meilleurs solutions sachant que le dictionnaire n'est pas la solution mais bien une meilleur. 


     


    Sans compter la fois ou le nom est à  l'index 123 et que tu as dû les compter à  la main parce que c'est pas trop possible de faire autrement (sauf si tu fais une fonction qui te renvoie l'index du nom dans le tableau) un gage de simplicité.


     


    Mais la tu vas me dire que ça ne vient pas d'un web service et que du coup tu sais et que ça ne risque rien donc pas de souci fait comme bon te semble et on en reparlera dans ton prochain post "ça fonctionnait y a une semaine".


  • AliGatorAliGator Membre, Modérateur

    Bon ok alors du coup ce que tu me dis c'est que ton tableau inclue dans "objects" a un ordre aléatoire, comment tu fais pour récupérer des données dans un objet que tu ne connais pas? 
    [...]
    Je sais que je te rabats les oreilles avec mais pour moi dans ce genre de cas si tu ne veux pas faire de model de données ce qui pour moi est un tort mais bon pourquoi pas au moins utilise des dictionnaire c'est mieux rangé et on se fou de l'ordre ça se compare plus facilement et pour le relire c'est que du bonheur.

     

    Ah oui c'est sur que pour relire self.nameLabel.text = [objects objectAtIndex:12]; c'est super ça se lit bien en plus.
    Un jour le dev du web service rajoute un champ dans la fiche personnage et il l'ajoute à  l'index 1 le fourbe et du coup dans ton nom tu te retrouves avec le titre d'une bande dessiné ou le nom de son chien. Pire l'anciens index 11 était son age en NSNumber et la tu te retrouve avec un jolie plantage. C'est pas une question de préférence on fait pas forcement les choses parce qu'on aime pas faire autrement mais parce qu'on sait que c'est une meilleurs solutions sachant que le dictionnaire n'est pas la solution mais bien une meilleur. 
     
    Sans compter la fois ou le nom est à  l'index 123 et que tu as dû les compter à  la main parce que c'est pas trop possible de faire autrement (sauf si tu fais une fonction qui te renvoie l'index du nom dans le tableau) un gage de simplicité.
     
    Mais la tu vas me dire que ça ne vient pas d'un web service et que du coup tu sais et que ça ne risque rien donc pas de souci fait comme bon te semble et on en reparlera dans ton prochain post "ça fonctionnait y a une semaine".

    +1000 Nasatya.
Connectez-vous ou Inscrivez-vous pour répondre.