Crash: Unexpected outstanding background CATransaction

HarloHarlo Membre

Hello,

Un crash que je n'arrive pas à éviter.

Je charge une vue, les couvertures n'étant pas en cache je les extrais. dès que je change de dossier ça va encore mais c'est quand je fais un scroll de la sidebar que ça crash...

J'ai essayé quelques trucs mais rien n'y fait pour le moment.

Si je désactive cette ligne, ça ne crache pas: https://github.com/Old-Geek/Librairie/blob/master/Librairie/Image/ImageCache.m#L57
mais ça charge pas mon image :disappointed:

Si l'image est déjà présente en cache tout fonctionne correctement vu que c'est quasi instantané.

Une idée ?

Réponses

  • PyrohPyroh Membre

    Essaie de remplacer

    dispatch_sync(dispatch_get_main_queue(), ^{
    
        imageView.image = image;
        [progress stopIndicator];
    
    });
    

    en

    dispatch_async(dispatch_get_main_queue(), ^{
    
        imageView.image = image;
        [progress stopIndicator];
    
    });
    
  • HarloHarlo Membre

    @Pyroh a dit :
    Essaie de remplacer

    Aucune différence

  • PyrohPyroh Membre

    Faudrait debugger alors. Malheureusement je n'ai pas le temps maintenant 😧

  • HarloHarlo Membre

    Faut que je me penche sur le sujet, j'ai bien ajouté un CA_DEBUG_TRANSACTIONS=1 mais je vois pas de diff dans le retour. C'est p'tet collé dans un fichier ?

  • LarmeLarme Membre

    Product/Scheme/Edit Scheme/Run/Diagnostic

    Je ne sais plus lesquels il faut cocher exactement, mais regarde pour faire en sorte de faire un breakpoint lorsqu'une update UI se fait en background (alors que ça doit toujours passer par le main).

  • PyrohPyroh Membre

    Bon j'ai trouvé. Enfin je pense.
    Tu appelle [image resize:coversize] dans un block asynchrone mais cette méthode fait appel à des fonctions qui vont dessiner directement dans un NSGraphicContext. À part cas très particulier tu ne peux pas le faire depuis ailleurs que le main thread c'est comme ça. Fais un peu ton marché dans ce post chez NSHipster pour trouver une autre méthode ou fait ton resize dans le main thread.

  • HarloHarlo Membre

    Merci :)

    Je vais aussi regarder du coté de SDImageWeb, je l'ai modifié pour qu'il utilise exactement la même méthode (le redimensionnement intégré à interfacebuilder est très crade) et ça passe tout seul.

  • HarloHarlo Membre
    16 mai modifié #9

    Y'a quand même une chose étrange...

    J'ai collé ça dans le resize histoire de
    NSLog(@Will call reloadData from %@", [NSThread isMainThread] ? @main thread : @background);

    2019-05-16 21:28:36.280306+0200 Librairie[31868:3623329] Will call reloadData from main thread
    2019-05-16 21:28:36.281988+0200 Librairie[31868:3623329] Will call reloadData from main thread
    2019-05-16 21:28:36.283647+0200 Librairie[31868:3623329] Will call reloadData from main thread
    2019-05-16 21:28:36.285444+0200 Librairie[31868:3623329] Will call reloadData from main thread
    2019-05-16 21:28:42.291790+0200 Librairie[31868:3623442] Will call reloadData from background
    2019-05-16 21:28:42.319395+0200 Librairie[31868:3623672] Will call reloadData from background
    2019-05-16 21:28:42.343699+0200 Librairie[31868:3623458] Will call reloadData from background
    2019-05-16 21:28:42.417138+0200 Librairie[31868:3623421] Will call reloadData from background

    Main ou pas ça change absolument rien, c'est uniquement quand ça resize dans un dossier, que j'en change avant que toute les couverture aient été resize et que je scroll l'outline view

    Si je change juste de dossier avant la fin, rien. Si je scroll sans changer de dossier, rien.

    "CoreAnimation: warning, encountered thread with uncommitted CATransaction; set CA_DEBUG_TRANSACTIONS=1 in environment to log backtraces, or set CA_ASSERT_MAIN_THREAD_TRANSACTIONS=1 to abort when an implicit transaction isn't created on a main thread.\n"

    @Uncommitted CATransaction. Set CA_DEBUG_TRANSACTIONS=1 in environment to debug.

    Je lui ai mis pourtant

  • LarmeLarme Membre

    As-tu essayé ceci : https://stackoverflow.com/questions/44943995/what-is-main-thread-checker-in-xcode afin que ton code se bloque à l'endroit où un appel d'UI est fait en background?

  • HarloHarlo Membre

    Merci pour l'info, effectivement c'est beaucoup plus bavard :)

    Je pense tenir une piste. Chaque fois que je change de dossier je recharge complètement la vue (currentContentViewController = [[NSViewController alloc] initWithNibName:@Folder bundle:nil];)

    En mettant simplement à jour les données de collectionview je n'ai plus de crash.
    Par contre, il me laisse les anciennes couverture en place temps que ça n'a pas chargé les nouvelles, ça fait crade.

  • HarloHarlo Membre

    Mouais, ça bug plus en faisant ça et j'initialise les items avec un fond par défaut pour éviter cet effet de persistance des covers. Reste à trouver un moyen de créer une queue purgeable pour que ça arrête la mise en cache de ce qui n'a plus besoin d'être affiché.

  • LarmeLarme Membre

    @Harlo a dit :
    En mettant simplement à jour les données de collectionview je n'ai plus de crash.
    Par contre, il me laisse les anciennes couverture en place temps que ça n'a pas chargé les nouvelles, ça fait crade.

    Il n'y a pas de prepareForReuse sur macOS ?

  • PyrohPyroh Membre

    @Larme a dit :

    @Harlo a dit :
    En mettant simplement à jour les données de collectionview je n'ai plus de crash.
    Par contre, il me laisse les anciennes couverture en place temps que ça n'a pas chargé les nouvelles, ça fait crade.

    Il n'y a pas de prepareForReuse sur macOS ?

    Si.

  • HarloHarlo Membre

    si mais ça recycle, c'est justement ce que je ne veux pas

  • PyrohPyroh Membre

    @Harlo a dit :
    si mais ça recycle, c'est justement ce que je ne veux pas

    Une raison à ça ?

  • HarloHarlo Membre
    17 mai modifié #17

    ben ouais, quand je change de vue je ne veux pas que les mêmes images soient affiché, ce qui se passe avec reuse

  • LarmeLarme Membre
    > @Harlo a dit :
    > ben ouais, quand je change de vue je ne veux pas que les mêmes images soient affiché, ce qui se passe avec reuse

    Alors le reuse est un concept important. Le prepareForReude doit être utiliser pour reset les valeurs. Du genre mettre à nil les images.
  • HarloHarlo Membre

    Je vais regarder de plus près alors

  • HarloHarlo Membre

    Effectivement ça évite des soucis.

    Merci :)

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