views:

99

answers:

1

Hello,

I'm trying to change the enabled property of an UIBarButtonItem after doing some stuff in an NSThread. After pressing the button I set the enabled to NO then perform the threaded part and at the end I try to re enable the button. Fairly basic.

Somehow this fails, however I'm able to change any other property of the the UIBarButtonItem correctly (for ex. title).

What am I doing wrong here?

Many thanks in advance!

@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];
}
+2  A: 

You want performSelectorOnMainThread instead.

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

Always do anything that touches the UI on the main thread.

But sometimes passing arguments like this is funky too. I find it best to wrap up everything you need done in another method

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

Then call that with

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

Now you can do as much other UI stuff as you want without worry about it.

Squeegy
I just amended my answer a bit with a more robust approach. If that doesn't work, you will have to clarify what exactly "didn't work" means. Errors? The new value you set is ignored? You may have a bug elsewhere if this doesn't work.
Squeegy
The second part of your answer is working great (calling the mysub_complete), Thanks!However let me add the following: originally I was using the performSelectorOnMainThread (the performSelectorInBackground was just a leftover of one of the thousands trials) but it wasn't working (button doesn't reenable). Any idea why that?
Tomas
There can be some strage translation sometimes using `withObject:[NSNumber numberWithBool:YES]` instead of simply `YES`. `performSelectorOnMainThread` is designed to take a single object argument, and behavior for non object arguments is somewhat undefined. So it's best to avoid it.
Squeegy