Passing primitives through performSelectorOnMainThread

Chance Hudson picture Chance Hudson · May 25, 2011 · Viewed 8k times · Source

Ok, so say i have a second thread running, but it wants to manipulate something on the main thread, like a UI item.

-(void)backgroundThread
{
    [myButton performSelectorOnMainThread:@selector(setEnabled:) withObject:(BOOL)YES waitUntilDone:YES];
     // right here, how could i pass this BOOL to the function
}

I've tried using NSNumber's numberWithBOOL, but the NSButton doesn't accept it.

Answer

user557219 picture user557219 · May 25, 2011

You cannot use performSelectorOnMainThread:withObject:waitUntilDone: with an argument that isn’t an Objective-C object, and you cannot use NSNumber because there’s no automatic unboxing from objects to primitive types.

One solution is to implement a similar method that accepts a button as an argument and call that method instead.

For example, in that same class:

- (void)enableButton:(NSButton *)button {
    [button setEnabled:YES];
}

and

-(void)backgroundThread{
    [self performSelectorOnMainThread:@selector(enableButton:)
                           withObject:myButton
                        waitUntilDone:YES];
}

Another solution is to implement a category on NSButton with an alternative method (e.g. -setEnabledWithNumber:), and use that method instead:

@interface NSButton (MyButtonCategory)
- (void)setEnabledWithNumber:(NSNumber *)enabled;
@end

@implementation NSButton (MyButtonCategory)
- (void)setEnabledWithNumber:(NSNumber *)enabled {
    [self setEnabled:[enabled boolValue]];
}
@end

and

-(void)backgroundThread{
    [myButton performSelectorOnMainThread:@selector(setEnabledWithNumber:)
                               withObject:[NSNumber numberWithBool:YES]
                            waitUntilDone:YES];
}