(Réglé) Sérialisation très longue

2»

Réponses



  • Ouch oui j'avais pas vu cette ligne mais c'est clair celle là  elle fait très mal... du chargement synchrone (donc bloquante) d'une URL réseau, qu'elle idée...




     


    C'est du synchrone ça ? Oo


     


    Comment je fais pour le passer en asynchrone stp

  • Joanna CarterJoanna Carter Membre, Modérateur
    juillet 2014 modifié #33

    Comme je t'ai dit pour le sérialisation


  • Ben77650Ben77650 Membre
    juillet 2014 modifié #34

    Johanna ça marche effectivement, mais on doit attendre très longtemps avant l'affichage des images


     


    Ma 1ère image s'affiche après 11 secondes, ma 2nde 14 secondes après le lancement de ma vue , et ma 3ème après 24 secondes...


     


    Mes utilisateurs risquent de penser qu'il n'y a pas d'image, c'est gênant :/



    if([lienImg isEqual:_baseURL])
        {
            cell.imageOffre.image=[UIImage imageNamed:@no_photo.png];
        }
        else
        {
            /*[self downloadImageWithURL:urlImg completionBlock:^(BOOL succeeded, UIImage *imageOff) {
                cell.imageOffre.image=imageOff;
            }];*/
            
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
                           {

            cell.imageOffre.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:urlImg]];
                           });
        }

  • AliGatorAliGator Membre, Modérateur
    C'est pas genre une discussion qu'on a déjà  eu plusieurs fois ? Sinon je t'invite à  chercher sur les forums du côté de AFNetworking et son extension UIImage+AFNetworking qui fait ça pour toi (parce que sinon surtout avec le recyclage des UITableViewCell qui peuvent avoir disparu entre le moment où tu lances le chargement de l'image et le moment où l'image est chargée, du coup c'est costaud à  faire soi-même si tu maà®trises pas un peu tout ça. On en parle dans plusieurs posts du forum.


    Y'a aussi SDImageView qui propose le même genre de trucs pour te faciliter les choses sur le chargement asynchrone d'images via une URL.


  • Comment je fais pour le passer en asynchrone stp




     


    Ben j'ai l'impression que tu as décas posé cette question et tu as eu les réponses. Tu as même posté le code pour aider les autres qui ont le même problème :)


     


    http://forum.cocoacafe.fr/topic/12567-régléoptimisation-uitableview-uiimage/?hl=asynchrone

  • Ah oui Samir je m'en souvenais pas, merci :D


     


    Ali, y'a rien qui m'indiquait que c'était du synchrone, aucun mot susceptible de me faire tilter que ça venait de la...


  • Ben77650Ben77650 Membre
    juillet 2014 modifié #38

    Effectivement, c'est bon, merci à  ceux m'ayant aidé, souci réglé ;)


  • AliGatorAliGator Membre, Modérateur


    Comme je t'ai dit pour le sérialisation

    non pour des requêtes réseau c'est déconseillé d'utiliser dispatch_async + des méthodes synchrones à  l'intérieur du dispatch_async. NSURLConnection n'est pas prévu pour et ça va mettre beaucoup + de temps que si tu utilises le mécanisme de RunLoop pour lequel NSURLConnection est prévu.


    Pour faire des requêtes asynchrone il faut toujours utiliser [NSURLConnection sendAsynchronousRequest:queue:handler:] plutôt que d'appeler les méthodes synchrones et d'essayer soi-même de les rendre asynchrone dans un dispatch_async. Quand y'a des méthodes déjà  toutes faites pour faire de l'asynchrone, toujours les utiliser plutôt que d'utiliser les synchrones dans un thread.



    Après comme je viens de le dire tout ça pourrait marcher dans le cas où les images sont chargées dans un tableau, ou bien dans une UIImageView qui reste tout le temps là . Mais ici apparemment on est dans une TableView, et les cellules des tableView sont recyclées quand on scroll ce qui fait que l'image qu'on a demandé à  l'instant T pour une cellule, quand elle arrivera la cellule aura eu le temps d'être recyclée pour servir à  un autre Article donc tu risques d'affecter l'image à  la mauvaise cell au final !


    C'est pour ça que SDImageView ou UIImageView+AFNetworking te permettent de contourner ça et gérer ces cas un peu difficiles.
  • samirsamir Membre
    juillet 2014 modifié #40


    Ali, y'a rien qui m'indiquait que c'était du synchrone, aucun mot susceptible de me faire tilter que ça venait de la...




    Tu n'as qu'a lire la documentation de la méthode si tu n'es pas sur. 


     


    https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html#//apple_ref/occ/clm/NSData/dataWithContentsOfURL:


     


    Un petit tutorial en Fraçais pour l'utilisation de Intruments. Tu n'auras pas passé autant du temps sur ce bug si tu avait bien profilé dés le début. 


     


    http://www.raywenderlich.com/fr/28722/comment-utiliser-les-instruments-dans-xcode


  • AliGatorAliGator Membre, Modérateur

    Ali, y'a rien qui m'indiquait que c'était du synchrone, aucun mot susceptible de me faire tilter que ça venait de la...

    la doc le dit et surtout c'est logique de toute façon vu que tu donnes une URL et tu t'attends à  ce qu'il te retourne une UIImage directement en valeur de retour. Comment veux-tu qu'il te retourne l'UIImage directement dans la valeur de retour de la fonction sans être obligé d'attendre d'avoir téléchargé l'image pour te la retourner en retour ?!


    Pour que ce soit asynchrone c'est à  dire que la méthode n'attente pas d'avoir téléchargé l'image avant de continuer le code, et retourne l'image bien plus tard quand elle aura enfin été téléchargée, il faudrait que la méthode retourne void et signale quand elle a fini au moyen d'un block (ou d'une méthode de délégate ou autre, bref un moyen de fournir l'image plus tard et pas immédiatement)
  • Joanna CarterJoanna Carter Membre, Modérateur


    non pour des requêtes réseau c'est déconseillé d'utiliser dispatch_async + des méthodes synchrones à  l'intérieur du dispatch_async. NSURLConnection n'est pas prévu pour et ça va mettre beaucoup + de temps que si tu utilises le mécanisme de RunLoop pour lequel NSURLConnection est prévu.




     


    Pardon. Je n'ai pas vu que c'était une requête réseau



  • Un petit tutorial en Fraçais pour l'utilisation de Intruments. Tu n'auras pas passé autant du temps sur ce bug si tu avait bien profilé dés le début. 


     


    http://www.raywenderlich.com/fr/28722/comment-utiliser-les-instruments-dans-xcode




    Déjà  lu à  2 ou 3 reprises sans comprendre le fonctionnement

  • Joanna CarterJoanna Carter Membre, Modérateur
    juillet 2014 modifié #44

    Petit cadeau pour Ben



    @interface SerializableRepository : NSObject

    @property (strong, nonatomic, readonly) NSArray *objets;

    - (void) ajouterTab:(NSArray *)tab;

    - (void) supprimerTab:(NSArray *)tab;

    @end


    @interface SerializableRepository ()

    @property (strong, nonatomic, readonly) NSMutableArray *mutableObjets;

    @property (strong, nonatomic, readonly) NSURL *fichierURL;

    @end


    @implementation SerializableRepository

    @synthesize mutableObjets = _mutableObjets;

    @synthesize fichierURL = _fichierURL;

    - (NSURL *)fichierURL
    {
    if (!_fichierURL)
    {
    NSURL *documentURL = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;

    _fichierURL = [documentURL URLByAppendingPathComponent:@objets.archive];
    }

    return _fichierURL;
    }

    - (NSMutableArray *)mutableObjets
    {
    if ([[NSFileManager defaultManager] fileExistsAtPath:self.fichierURL.path])
    {
    _mutableObjets = [[NSArray arrayWithContentsOfURL:self.fichierURL] mutableCopy];
    }
    else
    {
    _mutableObjets = [NSMutableArray array];
    }

    return _mutableObjets;
    }

    - (NSArray *)objets
    {
    return _mutableObjets;
    }

    - (void)ajouterTab:(NSArray *)tab
    {
    [self.mutableObjets addObject:tab];

    [self.mutableObjets writeToURL:self.fichierURL atomically:YES];
    }

    - (void)supprimerTab:(NSArray *)tab
    {
    NSUInteger indexASupprimer = [self.objets indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
    {
    NSSet *objetSet = [NSSet setWithArray:obj];

    NSSet *tabSet = [NSSet setWithArray:tab];

    if ([objetSet isEqualToSet:tabSet])
    {
    *stop = YES;

    return YES;
    }

    return NO;
    }];

    if (indexASupprimer != NSNotFound)
    {
    [self.mutableObjets removeObjectAtIndex:indexASupprimer];
    }

    [self.mutableObjets writeToURL:self.fichierURL atomically:YES];
    }

    @end


    Petites corrections


  • Merci Joanna c'est sympa de ta part




  • Déjà  lu à  2 ou 3 reprises sans comprendre le fonctionnement




     


    Ah bon, c'est étrange que tu ne comprennes pas, parce que le tutorial se base EXACTEMENT sur la même erreur que toi : charger une image distante avec la même méthode que toi.  :'(


     


    From Tutorial :


    Maintenant vous pouvez voir quel est le problème. NSData's dataWithContentsOfURL NSData blocs(c'est-à  ne PAS retourner) jusqu'à  ce que les données ont été Téléchargées. à‰tant donné que cette demande va vers l'Internet pour saisir les données, chaque appel pourrait prendre jusqu'à  quelques secondes pour revenir. Cette méthode est exécutée sur le thread principal, et par conséquent l'interface de l'utilisateur est entièrement empêchés de d'être mise à  jour, tandis que les données d'image Téléchargées.

     


  • J'ai juste lu le chapitre "Temps de profilage aussi, pas la suite", j'ai commencé à  lire le début de "exploration approfondie" et il m'a perdu avec ses chiens et ses chats donc j'ai abandonné, en me disant que c'était surement pas très utile ^^




  • Déjà  lu à  2 ou 3 reprises sans comprendre le fonctionnement




     


     




    J'ai juste lu le chapitre "Temps de profilage aussi, pas la suite", j'ai commencé à  lire le début de "exploration approfondie" et il m'a perdu avec ses chiens et ses chats donc j'ai abandonné, en me disant que c'était surement pas très utile ^^




     


    Ben alors, t'as lu ou t'as pas lu ?!

  • AliGatorAliGator Membre, Modérateur
    juillet 2014 modifié #49
    Moi j'ai voulu faire le tour du pâté de maison avec ma voiture du coup j'ai lu le manuel et il parlait d'un truc clignotant j'ai pas compris. Enfin j'ai juste lu le paragraphe ou ils disent comment tourner vu que je voulais juste tourner autour de ma maison, j'ai pas lu le reste je me suis dit que c'était pas utile. C'est quoi cette histoire d'accélérateur et de clé de contact dont tout le monde me parle ? J'y comprends rien je veux juste tourner moi !
Connectez-vous ou Inscrivez-vous pour répondre.