views:

4419

answers:

5

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?

A: 

I'm not sure I understand your question, but the storage type for selectors is SEL.

Can Berk Güder
please see updated questions. Thank you!
erotsppa
+2  A: 

Please see: passing a method as an argument

ennuikiller
please see updated questions. Thank you!
erotsppa
A: 

If you don't want to specify an object just use nil.

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

If you need to pass an object to the selector it would look something like this.

Here I'm passing a string to the method "setText".

NSString *string = @"hello world!";
 [NSThread detachNewThreadSelector:@selector(setText:) toTarget:self withObject:string];


-(void)setText:(NSString *)string {
    [UITextField setText:string]; 
}
Brandon Schlenker
please see updated questions. Thank you!
erotsppa
+11  A: 

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;
    [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
Chuck
+1  A: 

Use NSValue, like so:

+(void)method1:(SEL)selector {
    NSValue *selectorValue = [NSValue value:&selector withObjCType:@encode(SEL)];
    [NSThread detachNewThreadSelector:@selector(method2:) 
                             toTarget:self 
                           withObject:selectorValue];
}

NSValue is intended as an object-wrapper for arbitrary non-object types.

BJ Homer
Senseful
True. Thanks for noticing; I've fixed it.
BJ Homer