(Réglé) Erreur rechargement d'une vue avec UITableView

Ben77650Ben77650 Membre
juillet 2014 modifié dans Apple Developer Programs #1

Bonjour à  tous, je me retrouve confronté à  un problème avec une UIView contenant une UITableView d'infos.


 


Dès que j'arrive sur la vue une première fois pas de problème notable.


 


Cependant si je recharge ma vue ou que je vais sur la page de détail des infos, et que je cherche à  revenir à  la vue précédente via:



MyViewController* myViewController = [[MyViewController alloc]init];
    [self.navigationController pushViewController:myViewController animated:NO];

Je me retrouve face à  cette erreur.


 



2014-04-23 09:33:50.544 MonApp[801:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array'


*** First throw call stack:


(


0   CoreFoundation                      0x0000000101d10495 __exceptionPreprocess + 165


1   libobjc.A.dylib                     0x0000000101a6f99e objc_exception_throw + 43


2   CoreFoundation                      0x0000000101cb6745 -[__NSArrayM objectAtIndex:] + 213


3   MonApp                        0x000000010000de42 -[MyViewController tableView:cellForRowAtIndexPath:] + 1362


4   UIKit                               0x00000001006f0f8a -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 348


5   UIKit                               0x00000001006d6d5b -[UITableView _updateVisibleCellsNow:] + 2337


6   UIKit                               0x00000001006e8721 -[UITableView layoutSubviews] + 207


7   UIKit                               0x000000010067c993 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 354


8   QuartzCore                          0x0000000104a32802 -[CALayer layoutSublayers] + 151


9   QuartzCore                          0x0000000104a27369 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 363


10  QuartzCore                          0x0000000104a271ea _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24


11  QuartzCore                          0x000000010499afb8 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 252


12  QuartzCore                          0x000000010499c030 _ZN2CA11Transaction6commitEv + 394


13  UIKit                               0x000000010061b024 _UIApplicationHandleEventQueue + 10914


14  CoreFoundation                      0x0000000101c9fd21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17


15  CoreFoundation                      0x0000000101c9f5f2 __CFRunLoopDoSources0 + 242


16  CoreFoundation                      0x0000000101cbb46f __CFRunLoopRun + 767


17  CoreFoundation                      0x0000000101cbad83 CFRunLoopRunSpecific + 467


18  GraphicsServices                    0x0000000103d41f04 GSEventRunModal + 161


19  UIKit                               0x000000010061ce33 UIApplicationMain + 1010


20  MonApp                        0x000000010001c853 main + 115


21  libdyld.dylib                       0x00000001023a85fd start + 1


22  ???                                 0x0000000000000001 0x0 + 1


)


libc++abi.dylib: terminating with uncaught exception of type NSException


(lldb) 



 


 


Merci d'avance à  ceux qui m'aideront.


 


PS: Ceux qui commenteront uniquement pour souligner mon faible niveau sont priés de s'abstenir.


 


Réponses

  • AliGatorAliGator Membre, Modérateur
    Quelqu'un a vu ma boule de cristal ?

    Sans le code il va me la falloir...
  • Ben77650Ben77650 Membre
    avril 2014 modifié #3

    Salut AliGator, et merci de ta réponse



    -(void)getAll{
        
        
        
        dispatch_queue_t downloadQueue = dispatch_queue_create("Get All Infos", NULL);
        
        dispatch_async(downloadQueue, ^{
            NSData *result = [self executePostCall];
            
            id strResult=nil;
            int cpt;
            NSError* error;
            strResult = [NSJSONSerialization JSONObjectWithData:result options:0 error:&error];
            
            liste = [[NSMutableArray alloc]init];
            
            for(cpt=0; cpt<[strResult count];cpt++)
            {
                NSDictionary *dicoTemp = [strResult objectAtIndex:cpt];
                NSMutableArray* arrayTemp = [[NSMutableArray alloc]init];
                
                [arrayTemp addObject:[dicoTemp objectForKey:@nom]];                         //0
                [arrayTemp addObject:[dicoTemp objectForKey:@img]];                      //1
                [arrayTemp addObject:[dicoTemp objectForKey:@dateheure]];                          //2
                [arrayTemp addObject:[dicoTemp objectForKey:@price]];                          //3
                [arrayTemp addObject:[dicoTemp objectForKey:@city]];                         //4
                [arrayTemp addObject:[dicoTemp objectForKey:@cat]];                     //5
                [arrayTemp addObject:[dicoTemp objectForKey:@zip]];                    //6
                [arrayTemp addObject:[dicoTemp objectForKey:@username]];                          //7
                [arrayTemp addObject:[dicoTemp objectForKey:@desc]];                   //8
                [arrayTemp addObject:[dicoTemp objectForKey:@key]];                            //9
                [arrayTemp addObject:[self getOptionFromId:[dicoTemp objectForKey:@key]]];     //10
                [liste addObject:arrayTemp];
                
            }
            
            
            
            [self reloadtabledata:liste];
        });
    }


    -(NSArray*)getOptionFromId:(NSObject*) entier
    {
        NSURL *link = [NSURL URLWithString:[NSString stringWithFormat:@%@", @http://mywebsite/getOptions.php]];
        NSMutableURLRequest *URLrequest = [NSMutableURLRequest requestWithURL:link];
        
        NSString *post = @"";
        post = [post stringByAppendingFormat:@key=%@&;", entier];
        
        post = [post stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSData *dataRequest = [post dataUsingEncoding:NSUTF8StringEncoding];
        URLrequest.HTTPBody = dataRequest;
        URLrequest.HTTPMethod = @POST;
        
        NSHTTPURLResponse *httpResponse = nil;
        NSError *httpError = nil;
        NSData *dataResponse = [NSURLConnection sendSynchronousRequest:URLrequest returningResponse:&httpResponse error:&httpError];
        if (httpError == nil && httpResponse.statusCode == 200) {
        } else {
            
        }
        
        id stringResult=nil;
        int cmpt;
        NSError* error1;
        stringResult = [NSJSONSerialization JSONObjectWithData:dataResponse options:0 error:&error1];
        
        tabOpt = [[NSMutableArray alloc]init];
        
        for(cmpt=0; cmpt<[stringResult count];cmpt++)
        {
            NSDictionary *tempDic = [stringResult objectAtIndex:cmpt];
            NSMutableArray* tempTab = [[NSMutableArray alloc]init];
            
            [tempTab addObject:[tempDic objectForKey:@identifiant]];           //0
            [tempTab addObject:[tempDic objectForKey:@nom]];          //1
            [tempTab addObject:[tempDic objectForKey:@valeur]];          //2
            [tempTab addObject:[tempDic objectForKey:@unite]];          //3
            [tabOpt addObject:tempTab];
            
        }
    //    if(tabOpt.count==0)
    //    {
    //        NSLog(@TABLEAU VIDE !!!);
    //        [tabOpt addObject:@TAB VIDE];
    //    }
    //    else
    //    {
    //        NSLog(@options: %@", tabOpt);
    //    }
        return tabOpt;
    }


    static NSString* const UCellIdentifier = @CelluleOffre;
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        Cellule* cell = (Cellule *)[tableView dequeueReusableCellWithIdentifier:UCellIdentifier];
        if(cell==nil){
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:UCellIdentifier owner:nil options:nil];
            cell = [nib objectAtIndex:0];
        }

        NSString* objet =[[liste objectAtIndex:indexPath.row] objectAtIndex:0];
        objet = [objet stringByReplacingOccurrencesOfString:@&quot; withString:@\"];
        cell.labelObjet.text=objet;
        
        NSString* imgLink=[[liste objectAtIndex:indexPath.row] objectAtIndex:1];
        NSString* lienImg = [NSString stringWithFormat:@%@%@", baseURL,imgLink];
        NSURL* urlImg = [NSURL URLWithString:[lienImg stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
        if([lienImg isEqual:baseURL])
        {
            cell.ImageOffre.image=[UIImage imageNamed:@no_photo.png];
        }
        else
        {
            cell.ImageOffre.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:urlImg]];
        }
        
        NSString* date=[[liste objectAtIndex:indexPath.row] objectAtIndex:2];
        date = [date stringByReplacingOccurrencesOfString:@- withString:@/];
        cell.labelDate.text=date;
        
        NSString* prix =[[liste objectAtIndex:indexPath.row] objectAtIndex:3];
        NSString* euro = @€;
        NSString* prixeuro = [NSString stringWithFormat:@%@ %@", prix, euro];
        cell.labelPrix.text=prixeuro;
        
        
        NSString* city =[[liste objectAtIndex:indexPath.row] objectAtIndex:4];
        NSString* ville=[[city componentsSeparatedByString:@,]objectAtIndex:0];
        cell.cityLabel.text=ville;
        
        
        cell.categLabel.text=[NSString stringWithString:[[liste objectAtIndex:indexPath.row] objectAtIndex:5]];
        
        NSLog(@LES OPTIONS : %@",[[liste objectAtIndex:indexPath.row] objectAtIndex:10] );
        
        return cell;
    }
  • Il faut que tu apprennes à  comprendre tes messages d'erreurs, et réduise le champ de cause de ton erreur.


    Là , il dit que tu as essayé d'accéder à  un index de ton array qui n'existe pas, car il est vide.

    Utilise des BreakPoint également, ou des NSLogs si tu veux pour savoir dans quelle méthode tu passes, à  quel endroit, etc.


  • Salut Larme,


     


    J'ai bien compris que l'index 1 est en dehors des bornes de mon tableau vide, mais je ne vois pas vraiment pourquoi la 1ère fois mon tableau se remplis, et pourquoi ce n'est pas le cas au 2nd passage


  • AliGatorAliGator Membre, Modérateur
    ça plante dans cellForRowAtIndexPath, mais cette méthode est longue et contient énormément d'appels à  objectAtIndex.

    Met des breakpoint et fais du pas à  pas pour déjà  comprendre à  quelle ligne exactement ça plante dans la méthode, et pour en profiter pour inspecter un peu quel est le contenu de tes variables.

    Tu comprendras alors qu'elle variable est problématique, quel tableau est devenu plus petit que ce que tu ne crois. Et du coup essayer de comprendre pourquoi il a changé dans le cas ou tu fais back par rapport au premier affichage.
  • Ben77650Ben77650 Membre
    avril 2014 modifié #7

    Bon j'ai trouvé la source du problème qui est donc dans la méthode getAll donnée plus haut (puisque quand je commente cette ligne plus de souci):



    [arrayTemp addObject:[self getOptionFromId:[dicoTemp objectForKey:@key]]];     //10

    Ma méthode getOptionFromId est la suivante:



    static NSMutableArray* tabOpt;


    -(NSArray*)getOptionFromId:(NSObject*) entier
    {
        NSURL *link = [NSURL URLWithString:[NSString stringWithFormat:@%@", @http://mywebsite/getOptions.php]];
        NSMutableURLRequest *URLrequest = [NSMutableURLRequest requestWithURL:link];
        
        NSString *post = @"";
        post = [post stringByAppendingFormat:@key=%@&;", entier];
        
        post = [post stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSData *dataRequest = [post dataUsingEncoding:NSUTF8StringEncoding];
        URLrequest.HTTPBody = dataRequest;
        URLrequest.HTTPMethod = @POST;
        
        NSHTTPURLResponse *httpResponse = nil;
        NSError *httpError = nil;
        NSData *dataResponse = [NSURLConnection sendSynchronousRequest:URLrequest returningResponse:&httpResponse error:&httpError];
        if (httpError == nil && httpResponse.statusCode == 200) {
        } else {
            
        }
        
        id stringResult=nil;
        int cmpt;
        NSError* error1;
        stringResult = [NSJSONSerialization JSONObjectWithData:dataResponse options:0 error:&error1];
        
        tabOpt = [[NSMutableArray alloc]init];
        
        for(cmpt=0; cmpt<[stringResult count];cmpt++)
        {
            NSDictionary *tempDic = [stringResult objectAtIndex:cmpt];
            NSMutableArray* tempTab = [[NSMutableArray alloc]init];
            
            [tempTab addObject:[tempDic objectForKey:@identifiant]];           //0
            [tempTab addObject:[tempDic objectForKey:@nom]];          //1
            [tempTab addObject:[tempDic objectForKey:@valeur]];          //2
            [tempTab addObject:[tempDic objectForKey:@unite]];          //3
            [tabOpt addObject:tempTab];
            
        }
    //    if(tabOpt.count==0)
    //    {
    //        NSLog(@TABLEAU VIDE !!!);
    //        [tabOpt addObject:@TAB VIDE];
    //    }
    //    else
    //    {
    //        NSLog(@options: %@", tabOpt);
    //    }
        return tabOpt;
    }

  • Ben77650Ben77650 Membre
    avril 2014 modifié #8

    J'ai beau regarder mes 2 tableaux (que sont tempTab et tabOpt) sont tous les 2 déclarés et initialisés (via le alloc init), donc je vois vraiment pas d'où ça peut venir :/


  • AliGatorAliGator Membre, Modérateur
    Déclarés et initialisés, certes, mais avec quelles valeurs (en particulier avec quel contenu) ?
    Il y a bien un moment où ces tableaux (ou leurs sous-tableaux) contiennent moins d'éléments que ce que la tableView croit, d'où le OutOfBounds que tu as.
  • Et comment puis je savoir cela s'il te plait ?


     


    J'ai beau mettre des Logs ça me les affiche au 1er passage, mais pas au 2nd


  • AliGatorAliGator Membre, Modérateur
    Si ça ne t'affiche pas de logs au second passage, c'est que ça crash avant d'atteindre ton NSLog.

    Met un breakpoint dans cellForRowAtIndexPath et utilise le mode pas à  pas pour avancer ligne de code par ligne de code.
    (Au premier passage vu que tu sais que ça ne va pas crasher tu peux faire "Continue" pour continuer d'exécuter le code, mais au 2ème passage tu fais du pas à  pas pour comprendre sur quelle ligne ça crash)
    Une fois que tu as trouvé à  quelle ligne de ton code de cellForRowAtIndexPath: l'appli se met à  crasher, tu vas pouvoir relancer l'appli et retester à  nouveau mais en t'arrêtant pile juste avant la ligne, et regarder un peu plus en détail ce qu'il y a dans tes variables. Quitte à  décomposer cette ligne en plusieurs lignes intermédiaires pour comprendre ce qui se passe étape par étape, genre ne pas faire un [[tab objectAtIndex:i]objectAtIndex:j] directement, mais faire un subtab = [tab objectAtIndex:i] sur une ligne et un [subtab objectAtIndex:j] sur la ligne suivante, pour décomposer et comprendre ce qui se passe.

    Enfin bref, tu fais du déboggage, quoi. T'as déjà  bien dû en faire dans d'autres langages, Java ou autre d'après ton parcours, y'a rien de nouveau, tu décomposes ton problème pas à  pas pour isoler et comprendre exactement où ça pose problème, quelle ligne et quelle instruction crash, et en regardant un peu les variables tu essayes de comprendre pourquoi. Du déboguage classique quoi.
  • Merci AliGator pour cette réponse.


     


    Je t'avoue que durant mon parcours (que ça soit scolaire ou pro) j'ai jamais eu de débogage à  faire, donc ça va vraiment être une découverte pour moi, j'ai un peu touché hier aux breakpoint, et donc au débug, et ça me paraissait relativement compliqué.


     


    Je vais essayer ça, et si vraiment j'ai trop de souci, je reviendrais vers toi ou vers un autre capable de m'aider


  • Ben77650Ben77650 Membre
    avril 2014 modifié #13

    Bon donc au 2nd passage,


     


    Il passe une première fois dans la fonction sans que ça plante.


     


    Ensuite il m'envoie sur 2 pages de thread - Thread 1: "0 objc_autoreleaseReturnValue" et "0 -[UITableView _updateVisibleCellsNow:]"   .C'est normal selon vous ?


     


    Et visiblement la dernière ligne qu'il me lis avant de planter est la suivante:



    NSString* objet =[[liste objectAtIndex:indexPath.row] objectAtIndex:0];

    Voila ce qu'il m'affiche concernant cette ligne:


     



    self = (MyViewController *) 0x10958b870


    indexPath = (NSIndexPath *) 0xc000000000008016


    tableView = (UITableView *) 0x10b043600


    cell = (Cellule *) 0x109235bd0


    objet = (NSString *) 0x1008e7ba6


    liste = (__NSArrayM * )@0 objects


    UCellIdentifier = (__NSCFConstantString *) @Cellule



  • AliGatorAliGator Membre, Modérateur
    Bon ben voilà , tu l'as ton problème. liste a 0 éléments et tu lui demandes de te retourner le premier.

    Après je sais pas ce que tu fais avec cette liste, tu dois sans doute la vider à  un moment et oublier de la re-remplir.
  • Bah visiblement non je ne la vide à  aucun moment c'est ça qui est plutot rare


     


    Les différentes occurences de liste ci dessous:



    static NSMutableArray* liste;

    methode executePostCall



    liste=reloadrecupall2;

    methode getAll



    liste = [[NSMutableArray alloc]init];
    liste addObject:arrayTemp];
    [self reloadtabledata:liste];

    methode cellForRowAtIndexPath



    NSString* objet =[[liste objectAtIndex:indexPath.row] objectAtIndex:0];
    NSString* imgLink=[[liste objectAtIndex:indexPath.row] objectAtIndex:1];
    NSString* date=[[liste objectAtIndex:indexPath.row] objectAtIndex:2];
    NSString* prix =[[liste objectAtIndex:indexPath.row] objectAtIndex:3];
    NSString* city =[[liste objectAtIndex:indexPath.row] objectAtIndex:4];
    cell.categLabel.text=[NSString stringWithString:[[liste objectAtIndex:indexPath.row] objectAtIndex:5]];
    //NSLog(@LES OPTIONS : %@",[[liste objectAtIndex:indexPath.row] objectAtIndex:10] );

    methode numberOfRowsInSection



    return liste.count;

    methode didSelectRowAtIndexPath



    detail.Offredetail=[liste objectAtIndex:indexPath.row];
        detail.AllOffres = liste;

    Et 4 instances de liste passées en commentaire

  • AliGatorAliGator Membre, Modérateur
    avril 2014 modifié #16

    static NSMutableArray* liste;

    Pardon ??!? C'est quoi cette hérésie ?


    liste=reloadrecupall2;

    Heu et reloadrecupall2 il est pas vide par hasard ?
  • En quoi c'est une hérésie de le mettre en static ?


     


    Concernant le reloadrecupall2



    - (void) reloadtabledata:(NSMutableArray*) reloadrecupall2{
        dispatch_async(dispatch_get_main_queue(),^{
            [actview stopAnimating];
            [loadingView removeFromSuperview];
        });
        liste=reloadrecupall2;
        [ListOffre performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    }

    .h



    - (void) reloadtabledata:(NSMutableArray*) reloadrecupall2;
  • Bon je n'y comprends plus rien, ça marche correctement actuellement, alors que ça marchais pas ce matin, et que j'ai rien modifié :/


  • AliGatorAliGator Membre, Modérateur
    C'est un peu long à  t'expliquer pourquoi c'est une hérésie de mettre en static. Mais en gros, les varibles globales, c'est le mal, ça va te poser tout plein de problèmes si tu ne sais pas les utiliser correctement, en particulier avec les problématiques de multi-threading. Et en plus, par définition du mot clé static, ta liste en plus d'être globale et d'avoir ses accès qui ne sont aucunement protégés (jolis risques de crash en cas de race conditions), elle est en + partagée par toutes tes instances.
    Au final, en plus des problèmes que ça peut te poser si tu ne l'utilises pas correctement, cela viole le principe de base de la POO où chaque objet a des propriétés/variables d'instance.

    Faut utiliser des @property (ou des variables d'instance à  la limite bien que maintenant c'est un peu obsolète). Ca fait partie des premières choses qu'on apprend dans les bouquins sur ObjC...
    (Je ne sais pas comment tu as appris l'ObjC, via des tutos, via un bouquin, via une formation...?)
  • Tu fais bien de me le dire, car j'ai nombre de propriétés en static.


     


    Et j'ai appris l'Objective C, par le biais de ma formation scolaire par des cours donné par un pro (enfin c'est ce qu'il nous dit ^^) dans le domaine de l'iOS (Son entreprise fait de la délégation de formateurs, des applications sur mesure, et des formations en informatique).


  • AliGatorAliGator Membre, Modérateur
    S'il t'a enseigné d'utiliser des variables statiques pour ce genre de trucs, c'est que c'est loin d'être un pro ^^

    Je dis pas, ça peut parfois servir d'utiliser des variables statiques globale (en particulier pour le pattern singleton, je crois que c'est le seul cas où j'en utilise, et encore c'est des variables statiques donc le scope est réduit à  la méthode sharedIntsance donc pas globales), mais c'est très très rare, et quand tu le fais faut avoir conscience des conséquences. Des constantes déclarées static, pourquoi pas ("static NSString* const kSomeString = @toto; par exemple), mais des variables statiques, non seulement c'est pas du tout dans la logique POO mais en plus tu vas au devant de bugs (type multithreading/race conditions/...) que tu risques d'avoir du mal à  corriger.

    Il y a peut être des concepts de POO à  réviser, là , comme le concept d'objets et de variables d'instance, etc. parce que c'est quand même un concept de base en Objective-C (et en POO en général)
  • C'est vrai qu'à  part dans les singletons/sharedinstance et des NSString (notamment pour les cellIndentifier des UITableViewCells), j'en utilise pas non plus.


  • Ben77650Ben77650 Membre
    avril 2014 modifié #23

    D'accord, merci je prends note de tes précieux conseils ;)


     


    Un int ou un BOOL en static ça passe ou vaut mieux aussi le mettre en property ?


  • AliGatorAliGator Membre, Modérateur

    C'est vrai qu'à  part dans les singletons/sharedinstance et des NSString (notamment pour les cellIndentifier des UITableViewCells), j'en utilise pas non plus.

    • Pour les singleton, ce sont des variables (et non des constantes) statiques, en effet, mais d'une part restreintes à  un scope local et pas global, et en plus c'est le seul cas où ça a du sens de les utiliser
    • Par contre pour les NSString comme les cellidentifier, ce ne sont pas des variables statiques, mais des constantes. Autant les variables globales c'est le mal (car leur accès n'est pas protégé ni thread-safe, et tout le tintouin), autant les constantes c'est le bien, et si ces constantes doivent avoir leur scope limité au fichier (et pas accessibles de l'extérieur), le mot clé "static" a alors tout son sens, mais je le répète dans ce cas ce ne sont pas des variables statiques mais des constantes, donc ça n'est pas soumis aux problèmes/risques évoqués plus haut

    D'accord, merci je prends note de tes précieux conseils ;)
     
    Un int ou un BOOL en static ça passe ou vaut mieux aussi le mettre en property ?

    Non, ça ne fait aucunement exception. "static int x" ou "static BOOL y" sont tout aussi mal et dangereux (en terme d'accès concurrentiel et risques sur le multi-threading, entre autres choses) que "static NSString* x" ou que "static NSArray* y", ça ne change rien.

    "static int const kWidth = 320;" là  par contre ça va, c'est une déclaration de constante, donc qui ne sera accédée qu'en lecture seule, donc pas de risque d'une lecture et une écriture concurrents générant un risque de race condition et de crash.



    Mais au delà  de leur utilisation pour déclarer une constante, ou d'une utilisation locale maà®trisée dans un cas très très particulier (le cas du singleton étant le seul que je vois qui soit acceptable), c'est les seuls cas où ça a du sens.
    Dans le cas où ton int ou ton BOOL a sémantiquement le sens d'une variable d'instance / propriété (en sens du vocabulaire de la POO, c'est pas restreint à  Objective-C, ça, ce sont les bases même de tout langage Objet), alors utilise une @property.

    Conceptuellement de toute façon ça n'a pas de sens de déclarer une variable globale alors que ce que tu manipules est attaché à  l'instance de ton objet, et non pas global. C'est comme si tu gérais un parc de voitures et qu'au lieu de déclarer une classe "Voiture" qui a une propriété "couleur" et "marque" et "modèle", tu mettais la "couleur" dans une variable statique et non une propriété... variable statique qui du coup est globale et pas liée à  ton instance. Du coup toutes les Voitures manipulées par ton application partageraient la même variable "couleur", au lieu que chaque voiture ait sa propre couleur...

    J'ai l'impression qu'il te faut réviser tes bases de POO...
  • Je veut bien qu'on me dise quel(s) attribut(s) mettre pour des int ou des Bool, car que je mette retain, strong, nonatomic, assign, cela me fait une erreur ^^


     


    Pour les Array, String, MutableArray, les attributs nonatomic et retain passent mais pas pour le reste ^^


     


    Sinon aurait tu oublié de me répondre pour ma UIScrollView Ali ? ^^


    (C'est pas dit méchamment, je sais que tu fais autre chose à  côté)


  • AliGatorAliGator Membre, Modérateur
    Si tu "mets les attributs nonatomic et retain" et que "ça passe" sans que tu comprennes trop pourquoi et ce que signifient ces attributs, il y a là  encore des choses à  relire, car c'est un point important à  connaà®tre, l'ownership des objets les uns avec les autres (pour éviter les retain cycle notamment).

    On ne met pas "retain" comme ça par hasard. D'ailleurs depuis ARC (qu'on utilise par défaut pour les nouveaux projets), le mot "retain" est obsolète, maintenant en terme de politique d'ownership, on parle de "weak" ou "strong" pour les objets, et "assign" pour les types scalaires.

    Ca ne servirait pas à  grand chose que de te dire "bah met assign pour un BOOL" sans t'expliquer la signification exacte et les conséquences de ces mots clés.

    Quand à  "nonatomic" c'est un autre mot clé qui n'a plus à  voir avec la politique d'ownership de la propriété, mais avec la façon dont les accesseurs doivent être codés, en particulier s'ils doivent être atomiques ou pas pour prévoir un lock en cas d'utilisation multithread ou pas. Et "readonly" ou "readwrite" de même sont encore d'autres attributs d'une propriété qui définient entre un 3e axe n'ayant rien à  voir avec strong/weak/assign/unsafe_unretained)

    Tout ça est un vaste sujet, que là  encore un bon bouquin va mieux t'apprendre qu'une réponse de 3km sur un forum où il y a trop à  expliquer.
  • Bon je vais devoir revoir mon code, depuis que j'ai passé de static à  @property il y a certains trucs qu'il n'apprécie pas ^^


     


    AliGator tu ne sais pas m'aider sur la UIScrollView stp ? ^^




  • Bon je vais devoir revoir mon code...




     


    Si tu en es à  cette étape, y a plusieurs anomalies à  corriger :


     


    Les conventions d'appellation Cocoa : getAll, strResult,....


    Utilise les constantes la ou il faut : http://mywebsite/getOptions.php,...


    ....


     


    Lien documentation sur les conventions d'appellation Cocoa :


     https://developer.apple.com/library/mac/documentation/cocoa/conceptual/codingguidelines/Articles/NamingMethods.html

  • Merci mais je ne vois pas où est le souci.


  • Ce n'est pas vraiment des erreurs mais des bonnes pratiques à  prendre en compte :


     


    Pour que les autres développeurs comprennent ton code facilement ( si tu travailles en équipe par exemple) il faut respecter certaines convention d'appellation (méthodes, classes, variables,...) d'Apple. Prenons  exemple de ton code.


    Exemple 1 :


    la méthode "getAll".


     


    Deux anomalies dans ce nom de méthode :


     


    1. Clarté : Y a aucun développeur qui va comprendre ce qu'elle fait ta méthode en lisant juste sa signature "getAll", on comprend qu'elle récupère tout mais quoi (des voitures, des articles,....). Il faut que les autres développeurs qui lisent ton code ( pour maintenance par exemple,...) puissent comprendre ce qu'elle fait ta méthode sans rentrer dans les détails. Donc la clarté des appellation documente ton code.


     


    Exemple 2 :


    "reloadrecupall2" : Pourquoi 112 ? à  mon avis il n'a rien à  faire ici.


     


    2. Dans les conventions d'appellation d'Apple, l'utilisation de "get" dans les noms de méthodes n'est pas nécessaire sauf si une ou plusieurs valeurs sont retournées par références. 


     


    Y a encore d'autres anomalies par rapport aux conventions d'appellation dans ton code :


    - Consistance :


           Dès fois tu utilise "strResult" et "stringResult". Ce n'est pas consistant.


           Tu mélanges le Français et l'anglais : "imgLink", "lienImg"


    - Abréviation : tu utilises "str" par exemple, utilise plutôt "string", prend exemple des API Apple ( stringValue,...).


    ...


     


     


    - Utilisation des constantes :


    Par exemple dans ton code : http://mywebsite/getOptions.php 


    Tu vas surement avoir d'autres méthodes qui vont faire appel à  tes Web Service,et aussi il viendra un jour ou tu vas avoir besoin de changer ton api ( replacer l'api de développement par celle du production,....)donc au lieu de chercher dans toutes les lignes du code "http..." et les changer, tu n'as qu'à  modifier ta constante dans un seul endroit.


     


    Et y a encore d'autres choses dans ton code que je te laisse découvrir tout seul :).  

  • Merci d'avoir pris le temps de m'expliqué


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