2010-08-06 14 views
0

J'essaye de changer la propriété enabled d'un UIBarButtonItem après avoir fait quelques trucs dans un NSThread. Après avoir appuyé sur le bouton, j'ai mis l'option sur NON, puis j'effectue la partie filetée et à la fin, j'essaie de réactiver le bouton. Assez basique.iPhone UIBarButtonItem setEnabled dans NSThread

D'une manière ou d'une autre ceci échoue, cependant je suis capable de changer n'importe quelle autre propriété de l'UIBarButtonItem correctement (par exemple le titre).

Qu'est-ce que je fais mal ici?

@interface myViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> { 
    IBOutlet UIBarButtonItem *myButton; 

} 
@property (nonatomic, retain) IBOutlet UIBarButtonItem *myButton; 

- (IBAction)mysub:(id)sender; 

@end 



@implementation myViewController 

@synthesize myButton; 

- (IBAction)mysub:(id)sender { 
[myButton setEnabled:NO]; 

    [NSThread detachNewThreadSelector:@selector(mysub_threaded) toTarget:self withObject:nil];  
} 

- (void) mysub_threaded { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    … do threaded stuff 

    [myButton performSelectorInBackground: @ selector(setEnabled :) withObject: [NSNumber numberWithBool:YES]]; 

    [pool drain]; 
} 
+0

setEnabled: prend un BOOL, pas un NSNumber *. –

+0

tc. Alors, quelle devrait être la bonne façon de passer l'argument BOOL à performSelectorOnMainThread, au lieu d'utiliser NSNumber? – Tomas

Répondre

2

Vous souhaitez utiliser performSelectorOnMainThread à la place.

[myButton performSelectorOnMainThread:@selector(setEnabled:) 
          withObject:[NSNumber numberWithBool:YES] 
         waitUntilDone:NO]; 

Faites toujours tout ce qui touche l'interface utilisateur du thread principal.

Mais parfois passer des arguments comme celui-ci est funky aussi. Je trouve qu'il vaut mieux envelopper tout ce que vous devez faire dans une autre méthode

- (void)mysub_complete { 
    [myButton setEnabled:YES]; 
} 

Ensuite, appelez que avec

[self performSelectorOnMainThread:@selector(mysub_complete) 
         withObject:nil 
        waitUntilDone:NO]; 

Maintenant, vous pouvez faire autant d'autres choses de l'interface utilisateur que vous voulez sans vous soucier de ce .

+0

J'ai juste modifié ma réponse avec une approche plus robuste. Si cela ne fonctionne pas, vous devrez clarifier ce que signifie exactement "ne fonctionne pas". Les erreurs? La nouvelle valeur que vous définissez est ignorée? Vous pouvez avoir un bug ailleurs si cela ne fonctionne pas. –

+0

La deuxième partie de votre réponse fonctionne très bien (appelez le mysub_complete), merci! Cependant permettez-moi d'ajouter ce qui suit: à l'origine j'utilisait le performSelectorOnMainThread (le performSelectorInBackground était juste un reste de l'un des milliers d'essais) mais il ne fonctionnait pas (le bouton ne peut pas être réactivé). Une idée pourquoi ça? – Tomas

+0

Il peut y avoir une traduction de strage utilisant parfois 'withObject: [NSNumber numberWithBool: YES]' au lieu de simplement 'YES'. 'performSelectorOnMainThread' est conçu pour prendre un seul argument d'objet, et le comportement pour les arguments non-objet est quelque peu indéfini. Donc, il vaut mieux l'éviter. –