Creating a selector from a method name with parameters

BlueDolphin picture BlueDolphin · Nov 18, 2008 · Viewed 124.6k times · Source

I have a code sample that gets a SEL from the current object,

SEL callback = @selector(mymethod:parameter2);

And I have a method like

 -(void)mymethod:(id)v1 parameter2;(NSString*)v2 {
}

Now I need to move mymethod to another object, say myDelegate.

I have tried:

SEL callback = @selector(myDelegate, mymethod:parameter2);

but it won't compile.

Answer

Jason Coco picture Jason Coco · Nov 18, 2008

SEL is a type that represents a selector in Objective-C. The @selector() keyword returns a SEL that you describe. It's not a function pointer and you can't pass it any objects or references of any kind. For each variable in the selector (method), you have to represent that in the call to @selector. For example:

-(void)methodWithNoParameters;
SEL noParameterSelector = @selector(methodWithNoParameters);

-(void)methodWithOneParameter:(id)parameter;
SEL oneParameterSelector = @selector(methodWithOneParameter:); // notice the colon here

-(void)methodWIthTwoParameters:(id)parameterOne and:(id)parameterTwo;
SEL twoParameterSelector = @selector(methodWithTwoParameters:and:); // notice the parameter names are omitted

Selectors are generally passed to delegate methods and to callbacks to specify which method should be called on a specific object during a callback. For instance, when you create a timer, the callback method is specifically defined as:

-(void)someMethod:(NSTimer*)timer;

So when you schedule the timer you would use @selector to specify which method on your object will actually be responsible for the callback:

@implementation MyObject

-(void)myTimerCallback:(NSTimer*)timer
{
    // do some computations
    if( timerShouldEnd ) {
      [timer invalidate];
    }
}

@end

// ...

int main(int argc, const char **argv)
{
    // do setup stuff
    MyObject* obj = [[MyObject alloc] init];
    SEL mySelector = @selector(myTimerCallback:);
    [NSTimer scheduledTimerWithTimeInterval:30.0 target:obj selector:mySelector userInfo:nil repeats:YES];
    // do some tear-down
    return 0;
}

In this case you are specifying that the object obj be messaged with myTimerCallback every 30 seconds.