Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to I pass @selector as a parameter?

For the method:

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:(id)SELECTOR]; 

How do I pass in a @selector? I tried casting it to (id) to make it compile, but it crashes in runtime.


More specifically, I have a method like this:

+(void)method1:(SEL)selector{ [NSThread detachNewThreadSelector:@selector(method2:) toTarget:self withObject:selector];    } 

It crashes. How do I pass in the selector without crashing, so that the new thread can call the selector when the thread is ready?

like image 635
erotsppa Avatar asked May 31 '09 20:05

erotsppa


2 Answers

The problem here isn't passing a selector to a method, per se, but passing a selector where an object is expected. To pass a non-object value as an object, you can use NSValue. In this case, you'll need to create a method that accepts an NSValue and retrieves the appropriate selector. Here's an example implementation:

@implementation Thing - (void)method:(SEL)selector {     // Do something }  - (void)methodWithSelectorValue:(NSValue *)value {     SEL selector;      // Guard against buffer overflow     if (strcmp([value objCType], @encode(SEL)) == 0) {         [value getValue:&selector];         [self method:selector];     } }  - (void)otherMethodShownInYourExample {     SEL selector = @selector(something);     NSValue *selectorAsValue = [NSValue valueWithBytes:&selector objCType:@encode(SEL)];     [NSThread detachNewThreadSelector:@selector(methodWithSelectorValue:) toTarget:self withObject:selectorAsValue]; } @end 
like image 182
Chuck Avatar answered Sep 22 '22 07:09

Chuck


You can convert between selectors and string objects using the NSStringFromSelector() and NSSelectorFromString() functions. So you can just pass string objects instead.

Alternately, if you don't want to change your methods, you can create an NSInvocation to create an invocation for your method call (since it can set up invocations with non-object arguments), and then to call it do [NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];

like image 22
user102008 Avatar answered Sep 24 '22 07:09

user102008