2010-07-06 2 views
0

J'ai une vue qui reçoit de nouvelles données d'un thread secondaire. Chaque fois que c'est le cas, il devrait se redessiner. Cependant, il ne joue pas bien avec la boucle d'exécution, et après un certain temps (c'est non-déterministe), je reçois des messages <Error>: kCGErrorIllegalArgument: CGSUnionRegionWithRect : Invalid region dans la console.Quelle est la bonne façon de synchroniser les appels vers un NSView?

Je ne suis pas sûr de la bonne façon de synchroniser les appels à [view setNeedsDisplay:YES] entre threads; Pouvez-vous m'aider?

Pour clarifier un peu, fil B (en fait une file d'attente d'envoi) donne un nouveau contenu à une vue en appelant ceci:

-(void)setImageBuffer:(unsigned char*)buffer 
{ 
    /* image handling stuff; thread-safe */ 

    [self setNeedsDisplay:YES]; // but this is not thread-safe 
} 

Et puis enfilez A, sur lequel fonctionne la boucle d'exécution, devrait afficher à nouveau la vue .

Répondre

1
-(void)setImageBuffer:(unsigned char*)buffer 
{ 
    /* image handling stuff; thread-safe */ 

    [self performSelectorOnMainThread:@selector(induceRedraw) 
          withObject:nil 
             // Don't just copy this; pick one... 
         waitUntilDone:YES or NO]; 
} 

-(void)induceRedraw 
{ 
    [self setNeedsDisplay:YES]; // but this is not thread-safe 
} 
+0

Meh. 'NSObject' était sûrement le dernier endroit que j'aurais pensé regarder. Merci beaucoup. – zneak

+0

Vous pourriez vouloir lire le "Threading Programming Guide", qui vous aurait donné un indice. – JWWalker

+0

@JWWalker: Peut-être que vous l'aviez conçu comme un empannage léger, mais votre commentaire apparaît comme insultant, ce qui est tout à fait déplacé. Personnellement, je n'avais aucune idée de la présence d'un tel guide et j'ai découvert mes connaissances par d'autres moyens. –

0

Avec GCD vous n'avez pas besoin de la méthode proxy supplémentaire:

dispatch_queue_t q = dispatch_get_main_queue(); 
dispatch_async(q, ^(void) { 
    [self setNeedsDisplay: YES]; 
}); 
Questions connexes