2017-04-30 1 views
2

Je voulais savoir pourquoi mon code s'exécute beaucoup plus lentement quand j'utilise dispatch_async par rapport à quand je ne l'utilise pas du tout. J'essaie de brouiller les bords de mon UIImage en le masquant et en utilisant UIGraphicsImageRenderer (Je ne sais pas si c'est le moyen le plus efficace ou pas ..) Mais quand je n'utilise pas dispatch_async, ça tourne beaucoup plus vite. Pourquoi donc? Voici mon code et le résultat que je reçois de mon code. Toute aide est très appréciée.Pourquoi utiliser dispatch_async est si lent comparé à ne pas l'utiliser du tout?

enter image description here

self.view.backgroundColor = [UIColor whiteColor]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       UIImage* Img = [UIImage imageNamed:@"1"]; 
       UIImageView * imageview = [[UIImageView alloc]initWithImage:Img]; 
       UIGraphicsImageRenderer * renderer = [[UIGraphicsImageRenderer alloc] initWithSize:Img.size]; 

       UIBezierPath*path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(20,20,170,170) cornerRadius:5.0]; 
       path.lineWidth = 20; 

       CAShapeLayer*shapeLayer = [CAShapeLayer new]; 
       shapeLayer.path=path.CGPath; 

       [shapeLayer setFillColor:[UIColor redColor].CGColor]; 
       [shapeLayer fillColor]; 

       UIImage *shapeImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context){ 
        [shapeLayer renderInContext: context.CGContext];}]; 

       CIImage * shapeCimage = [[CIImage alloc] initWithImage:shapeImage]; 
       CIFilter * gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"]; 
       [gaussianBlurFilter setValue:shapeCimage forKey: @"inputImage"]; 
       [gaussianBlurFilter setValue:@15 forKey:@"inputRadius"]; 

       CIImage * blurredCIImage = [gaussianBlurFilter valueForKey:kCIOutputImageKey]; 
       UIImage * blurredImage = [UIImage imageWithCIImage:blurredCIImage]; 

       UIImageView *maskedImageView = [[UIImageView alloc]initWithImage:blurredImage]; 
       maskedImageView.contentMode = UIViewContentModeScaleAspectFit; 
       maskedImageView.frame = imageview.frame; 
       imageview.layer.mask=maskedImageView.layer; 

       dispatch_async(dispatch_get_main_queue(), ^{ 
        [self.view addSubview:imageview]; 
       }); 
      }); 
+1

Où vous arrêtez/masquez la vue d'activité? – Paulw11

+0

Je m'excuse, j'ai oublié de supprimer cette partie de la question avant de la poster, c'est résolu maintenant. Mais mon problème est que dispatch_Async rend mon code beaucoup plus lent. Est-ce que je le fais mal? Je vous remercie. @ Paulw11 –

Répondre

3

Toutes les choses de l'interface utilisateur doit être effectuée sur la file d'attente principale. Sinon, cela pourrait entraîner des bugs (de temps en temps) et des performances incroyablement lentes.

La raison en est que UIApplication est configuré sur le thread principal.

Vous pouvez consulter ce tutoriel sur:

  1. http://blog.grio.com/2014/04/understanding-the-ios-main-thread.html

  2. https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW15.

meilleures salutations

+0

Merci, j'ai seulement mis à jour l'interface utilisateur dans la file d'attente principale, donc il n'y a aucun moyen que je puisse faire la première partie de mon code en arrière-plan? Parce que j'ai une vue de collection horizontale sous cette vue que je ne veux pas être bloqué pendant que l'utilisateur fait défiler et sélectionne différents effets. Ne devrais-je pas faire ces choses en arrière-plan pour ne pas bloquer la file d'attente principale pour d'autres mises à jour d'interface utilisateur telles que le défilement de la collection? –

+1

Vous pouvez consulter la bibliothèque de Facebook pour le kit d'affichage asynchrone: https://code.facebook.com/posts/721586784561674/introducing-asyncdisplaykit-for-smooth-and-responsive-apps-on-ios/ – dava

2

GCD gère les files d'attente avec des priorités différentes. Plus la priorité est élevée, plus le pourcentage de temps de traitement des tâches de cette file d'attente est important.

Apple a conçu son système de priorité afin que l'interaction de l'utilisateur (le thread principal) reçoive la plus haute priorité, afin de garder l'interface utilisateur sensible. DISPATCH_QUEUE_PRIORITY_DEFAULT est une priorité inférieure à celle du thread principal, de sorte qu'un travail soumis avec cette priorité prendra plus d'une exécution sur le thread principal. Vous pourriez essayer d'utiliser DISPATCH_QUEUE_PRIORITY_HIGH comme expérience, vous ne devriez pas le faire dans une application de production car cela ralentira l'interface utilisateur (et Apple peut rejeter votre application.)

+0

Merci d'avoir signalé que mais j'ai déjà essayé DISPATCH_QUEUE_PRIORITY_HIGH et les résultats étaient tout aussi bas que les priorités inférieures. Vraiment lent pas beaucoup de différence à l'aide de la priorité par défaut. Demandez simplement, vous recommanderiez également d'utiliser AsyncDisplayKit de Facebook pour ce cas aussi? Merci @DuncanC –