web-dev-qa-db-fra.com

IOS semaphore_wait_trap sur le thread principal provoquant le blocage de l'interface utilisateur

J'ai une longue fonction en cours d'exécution dans une file d'attente de travail asynchrone (série). Je sais que parfois cette fonction est suspendue dans un appel openCV particulier. Pour une raison quelconque, ce blocage provoque également le blocage du thread principal. Lorsque je fais une pause et que je passe en mode débogage, je vois qu’il y a un appel à

semaphore_wait_trap()

sur le fil principal (file d'attente)

Je peux suspendre le fil en attente (ma file d'attente de travailleur) en mode débogage, puis cette interruption disparaît et l'interface graphique devient réactive sur le téléphone.

Après la pause du thread de travail, l’interface graphique répond pendant 1 à 2 secondes (jusqu’à ce que ce thread soit réactivé), puis l’interface utilisateur cesse de répondre.

Ce thread n'effectue aucun appel dispatch_sync() au thread principal/à la file d'attente

Est-il possible que IOS mette en pause le thread principal (le "piège") parce que le programme de travail est en cours d'exécution?

Puis-je le forcer à retirer le bloc?

J'ajoute quelques écrans d'impression de la pile en mode débogage.

Avant de suspendre la file d'attente suspendue:

Main Queue Stack

Et le fil suspendu:

Hanging Queue

Et après avoir suspendu et suspendu la mauvaise file d'attente:

After Suspending

24
Avner Barr

Est-il possible que IOS mette en pause le thread principal (le "piège") parce que le programme de travail est en cours d'exécution? - NON. Je pense que votre problème est lié au dessin ou à la modification de certains éléments de l'interface utilisateur. Toutes les fonctions ne peuvent pas être appelées à partir du thread d'arrière-plan (par exemple, les modifications apportées aux éléments de l'interface utilisateur doivent être effectuées dans le thread principal.). Dans votre file d'attente série, si une méthode nécessite de modifier des éléments de l'interface utilisateur, vous devez l'appeler sur le thread principal, par exemple.

dispatch_async(dispatch_get_main_queue(), ^{
                //do some main thread job here
            });
)
2
Fahri Azimov

Peut-être avez-vous simplement oublié de conserver une variable dans l'appel de la fonction dispatch (Quant à moi, un mot clé statique a été omis avant la déclaration dispatch_once_t et l'envoi ne peut pas être traité avec la fonction inline). La trace de la pile était comme la tienne. C'était de ma faute.

+ (instancetype)sharedInstance
{
    (static was omitted) dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
} 
0
user2992955