performSelectorOnMainThread avec un délégué

CéroceCéroce Membre, Modérateur
mars 2012 modifié dans Objective-C, Swift, C, C++ #1
Bonjour à  tous,





Dans mon appli, j'ai un thread secondaire créé grâce à  une NSBlockOperation. Pour signaler la fin du traitement, je voudrais utiliser la délégation:


<br />
[delegate performSelectorOnMainThread:@selector(rendererDidRender:) withObject:self waitUntilDone:YES];<br />




Malheureusement, j'ai un warning qui me dit que la méthode n'est pas connue. La méthode est pourtant bien définie dans NSThread.h, sous la forme d'une catégorie sur NSObject:


<br />
@interface NSObject (NSThreadPerformAdditions)<br />
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;<br />






Mon délégué est déclaré ainsi:


<br />
@class CeMandelbrotRender;<br />
@protocol CeMandelbrotRenderDelegate &lt;NSObject&gt;<br />
- (void) rendererDidRender:(CeMandelbrotRender *)render;<br />
@end<br />
<br />
@interface CeMandelbrotRender : NSObject<br />
@property (nonatomic, strong) id &lt;CeMandelbrotRenderDelegate&gt; delegate;<br />






Que dois-je écrire pour que le compilateur sache que le délégué répond à  la méthode définie dans la catégorie NSThreadPerformAdditions ?

Réponses

  • Change ton

    [/color][color=#000000]id [/color][color=#666600]&lt;[/color][color=#660066]CeMandelbrotRenderDelegate[/color][color=#666600]&gt;[/color][color=#000000] [/color][color=#000088]delegate[/color][color=#666600];[/color]
    


    en



    NSObject[/color][color=#000000] [/color][color=#666600]&lt;[/color][color=#660066]CeMandelbrotRenderDelegate[/color][color=#666600]&gt;[/color][color=#000000] *[/color][color=#000088]delegate[/color][color=#666600];[/color]
    
  • CéroceCéroce Membre, Modérateur
    Merci! Evidemment, ainsi, ça fonctionne.

    (Bizarre, il me semblait avoir essayé).
  • Tu as dû faire un truc du genre NSObject * < ....> delegate. Faux ! image/smile.png' class='bbc_emoticon' alt=':)' />
  • CéroceCéroce Membre, Modérateur
    Oui, ça exactement.
  • AliGatorAliGator Membre, Modérateur
    mars 2012 modifié #6
    Sinon plutôt que de mettre une contrainte forte sur le type de ton delegate (le typer NSObject*) et utiliser performSelectorOnMainThread, tu pourrais utiliser GCD.



    De plus pour garder une cohérence, tu ne devrais pas forcément exécuter le code que tu appeles sur ton delegate forcément dans le mainThread, mais plutôt dans le thread appelant (celui qui a forké ton thread secondaire). Ou dans le cas de GCD, la queue sur laquelle s'exécute ton code avant que tu fork ton thread.



    Bon, ok, en général ce thread appelant (ou cette queue appelante) c'est la mainThread (la main Queue). Mais sait-on jamais, autant rendre ton code flexible et réutilisable.


    dispatch_queue_t callingQueue = dispatch_get_current_queue(); // qui sera sans doute la  dispatch_get_main_queue()<br />
    // blabla call de ton thread<br />
    dispatch_sync(callingQueue, ^{ [delegate [color=#000000][font=monospace][size=3]rendererDidRender:self]; });
    
    [/size][/font][/color]
  • CéroceCéroce Membre, Modérateur
    Pour mon programme, ça n'a pas d'importance parce que c'est une UIView qui crée les NSOperations et la NSOperationQueue, et donc c'est forcément sur le thread principal.



    Mais, justement, je me posais la question sur la manière de s'y prendre si ce n'était pas le thread principal.
  • AliGatorAliGator Membre, Modérateur
    Bah après c'est ce que je disais, si tu es sûr que c'est le main thread dans un premier temps même si c'est moins adaptatif, tu peux supposer que c'est le main thread, ou la mainQueue GCD.



    Et du coup tu peux garder ton delegate de type [font=courier new,courier,monospace]id<CeMandelbrotRenderDelegate> delegate[/font] et remplacer ton
    [delegate performSelectorOnMainThread:@selector(rendererDidRender:) withObject:self waitUntilDone:YES];
    
    par un simple
    dispatch_sync(dispatch_get_main_queue(), ^{ [delegate rendererDidRender:self]; });
    
  • CéroceCéroce Membre, Modérateur
    Oui, j'avais bien compris, merci pour cette précision.
  • Mais oui, il faut arrêter d'utiliser des performSelector et utiliser GCD partout !!!!

    Les Blocks c'est la vie image/thumbsup.gif' class='bbc_emoticon' alt='' />
Connectez-vous ou Inscrivez-vous pour répondre.