Réaction très lente après un click sur UITableView

J'ai un petit souci lorsque je veux instancier un viewController en fonction du choix de l'utilisateur dans une UITableView. Dans un premier temps, j'avais l'impression qu'il fallait deux clicks sur une même cellule et j'ai épluché les forums sur le sujet... Et j'ai donc vérifié que j'avais bien renseigné la méthode didSelectRow... et non didDeselectRow...


 


Mais en fait le problème n'est du tout le même. Il suffit bien d'un click pour obtenir le résultat souhaité, mais il faut beaucoup de patience (trop), car il se passe environ 5 à  6 secondes avant de voir apparaitre la bonne vue ! Ce qui est évidemment trop lent. 


 


Voici le code que j'ai :



-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row) {
case 0:
[self showMyFirstVC];
break;

case 1:
[self showMySecondVC];
break;

default:
break;
}
}

-(void)showMyFirstVC {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@Main bundle:nil];
MyFirstVC *theFirst=[sb instantiateViewControllerWithIdentifier:@MyFirstVC];
theFirst.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
theFirst.aVar=@Toto;
theFirst.delegate = self;
[self presentViewController:theFirst animated:YES completion:NULL];
}

-(void)showMySecondVC {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@Main bundle:nil];
MySecondVC *theSecond=[sb instantiateViewControllerWithIdentifier:@MySecondVC];
theSecond.anotherVar=@Titi;
theSecond.delegate = self;
[self presentViewController:theSecond animated:YES completion:NULL];
}


Apparemment, le didSelectRowAtIndexPath est appelé instantanément mais c'est dans les méthodes showMyFirstVC et showMysSecondVC que c'est long...


Quelqu'un a-t-il une idée de ce que j'ai fait comme boulette ?


 


Merci d'avance.


 


 


Réponses

  • ça arrive pour les 2 Controllers ?

  • Oui c'est pareil (en fait il y en a même 4 différents mais j'ai mis juste un échantillon de code). J'ai essayé de ne pas renseigner les différentes variables pour voir si çà  avait une influence sur le temps de chargement mais çà  ne change rien !

  • AliGatorAliGator Membre, Modérateur
    Commence par utiliser Instruments pour isoler précisément qui est le fautif.
  • Oui je suis justement en train d'essayer de comprendre comment fonctionne ce MNMNLND (censuré) d'Instrument !!!


     


    Merci Ali.


  • Une petite idée en passant, le fait d'instancier le storyboard avec 



    UIStoryboard *sb = [UIStoryboard storyboardWithName:@Main bundle:nil]

    çà  ne risque pas d'être un peu long si le storyboard est gros (environ une dizaine de vues) ?


     


    N'est-il pas mieux de créer un storyboard secondaire uniquement pour ces scènes ?


  • Je pense vraiment pas que ce soit le noeud du problème. Comme l'a dit AliGator les instruments peuvent t'aider à  comprendre d'où vient le problème. 


     


    À première vue je pensais que au chargement de tes Controllers tu exécutais quelque chose qui prenait un certain temps mais si ça arrive sur tous les Controllers ça ne semble pas être le problème.


  • Joanna CarterJoanna Carter Membre, Modérateur
    Si le code qui "crée" le prochain ViewController se trouve dans un des ViewControllers du même storyboard, tu peux essayer appeler self.storyboard.


  • Si le code qui "crée" le prochain ViewController se trouve dans un des ViewControllers du même storyboard, tu peux essayer appeler self.storyboard.




     


    Merci Joanna, je ne connaissais pas cette possibilité...


     


    Cependant, le problème ne vient pas de là , car 100% du temps est passé sur l'instruction :



    [self presentViewController:theSecond animated:YES completion:NULL];


    (J'ai enfin compris comment utiliser Instruments !!! Merci "Ray" !!!)


     


    Je vais voir si la nuit va me porter conseil.   ::)

  • Joanna CarterJoanna Carter Membre, Modérateur
    Qu'est-ce que tu fais dans le viewDidLoad et/ou viewWill/DidAppear ?


  • Qu'est-ce que tu fais dans le viewDidLoad et/ou viewWill/DidAppear ?




    C'est ce que je pensais aussi ça peut peut-être venir de ton viewDidLoad du controller que tu instancies.



  • Qu'est-ce que tu fais dans le viewDidLoad et/ou viewWill/DidAppear ?




     


    Bonjour et désolée pour la réponse tardive...


     


    Merci pour vos interventions à  tous les deux. En fait il n'y a pas de viewDidAppear et rien de bien compliqué dans le viewDidLoad, juste l'initialisation de quelques variables nécessaires pour la gestion d'une searchBar et d'une UITableView.



    - (void)viewDidLoad {
    [super viewDidLoad];
    _oneSelectedItem=@"";
    _allSelectedItems=[[NSMutableArray alloc] init];
    _mySearchBar.autocapitalizationType=UITextAutocapitalizationTypeAllCharacters;
    _mySearchBar.autocorrectionType=UITextAutocorrectionTypeNo;
    _mySearchBar.delegate=self;
    _myTable.delegate=self;
    _myTable.dataSource=self;
    _someItems=[[NSMutableArray alloc] initWithArray:_allItems];
    }

  • Je viens d'avoir une amélioration "provisoire" en supprimant deux lignes : autocapitalization et autocorrection que j'ai initiées directement depuis le storyboard.


     


    Quand je dis amélioration provisoire, c'est que la première apparition de la vue est rapide, mais si je quitte la vue (click sur "cancel" qui génère un dismiss via le delegate) et que je reviens dessus, je retrouve la lenteur initiale.


     


    En tout cas vous m'avez mise sur la voie, je continue d'explorer tout çà . Merci.


  • Alf1996Alf1996 Membre
    mars 2016 modifié #14
    Et bien toujours pareil, çà  rame et c'est aléatoire (un coup c'est rapide, un coup non).
     
    J'ai simplifié au maximum...
    J'ai essayé de mettre les quelques initialisations dans le viewWillAppear au lieu du viewDidLoad, et çà  n'a rien changé.
     
    Instruments me dit que 100% du temps est passé dans la méthode suivante (dans le nouveau VC)
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @CellChooseItem;
    ChooseItemTVCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    NSString *nameItem=[self.someItem objectAtIndex:indexPath.row];
    cell.mainLabel.text=nameItem;

    return cell;
    }

    et plus particulièrement sur le "dequeueReusableCell"...
     
    Vu que c'est la première fois que j'utilise les prototypeCells, j'ai dû faire un truc de travers, mais je ne vois pas quoi !
     
    Si vous avez une idée, je prends... Merci d'avance.  o:)
  • DrakenDraken Membre
    mars 2016 modifié #15

    Essaye de créer une mini-application avec une TableView et des cellules recyclables pour vérifier si tu as bien compris le truc. C'est très louche ce dequeueReusableCell prenant 100% du temps machine, alors qu'il est justement conçu pour économiser du temps.


     


    EDIT : En y réfléchissant, le problème vient certainement de la manière dont tu crées tes cellules recyclables. N'arrivant pas à  les recycler pour-je-ne-sais-quelle-raison le système crée un grand nombre de cellules, ce qui consomme de la mémoire et du temps.

  • Bonne idée !


     


    Comme je suis flemmarde, j'ai fait un peu plus simple : j'ai instancié le fameux VC non plus à  partir d'un click dans la tableView, mais à  partir d'un bouton (j'ai juste fait un copier coller sans avoir à  recréer un autre projet test), et là  çà  marche !


     


    Du coup ma question est la suivante : y-a-t-il une contre-indication à  instancier un VC contenant une tableview à  partir d'une autre tableView ? Du moins avec un storyboard, car avec des XIB çà  fonctionnait très bien...


  • Oui, voir mon message un peu plus haut... 


     




    Instruments me dit que 100% du temps est passé dans la méthode suivante (dans le nouveau VC)



    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @CellChooseItem ;
    ChooseItemTVCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    NSString *nameItem=[self.someItem objectAtIndex:indexPath.row];
    cell.mainLabel.text=nameItem;

    return cell;
    }


    et plus particulièrement sur le "dequeueReusableCell"...


     




     


    Par contre, si j'instancie le nouveau VC non plus à  partir d'une tableview, mais à  partir du click sur un bouton, et bien dans ce cas je n'ai plus de problème !!! C'est complètement dingue.

  • CéroceCéroce Membre, Modérateur

    Instruments me dit que 100% du temps est passé dans la méthode suivante (dans le nouveau VC)
    et plus particulièrement sur le "dequeueReusableCell"...

    Cette méthode instancie des cellules. Le prototype est-il particulièrement chargé? Utilises-tu des images, par exemple ?
  • Alf1996Alf1996 Membre
    mars 2016 modifié #19


    Cette méthode instancie des cellules. Le prototype est-il particulièrement chargé? Utilises-tu des images, par exemple ?


     



     


    Non pas du tout, juste un peu de texte dans un mutableArray (via une searchBar). Pas d'images. Au maximum une centaine d'items (61 exactement). Et en plus c'est hyper fluide lorsque le nouveau VC est instancié à  partir du click sur un bouton.

  • Hello !


     


    Perso j'ai aussi ce problème assez souvent, qui apparait de façon complètement aléatoire. J'ai trouvé un workaround, mais j'en suis pas super content...


    Apparement ça vient du fait que l'action n'est pas exécuté dans le thread principal. Du coup en forçant l'appel du controller avec :



    dispatch_async(dispatch_get_main_queue()) 

    ça fonctionne correctement... Mais c'est vraiment pas foufou. J'en avais marre d'essayer de comprendre d'où ça venait vu le caractère aléatoire.

  • Alf1996Alf1996 Membre
    avril 2016 modifié #21

    Merci pour ce retour. Quelque part çà  me rassure de voir que je ne suis pas seule à  avoir rencontré ce problème !


     


    Finalement, comme j'hésitais entre une UITableView et des UIButtons pour mon VC appelant (7 options seulement), j'ai opté pour la solution avec les boutons et du coup tout est rentré dans l'ordre...


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