Creating a selector from a method name with parameters

Objective CSelector

Objective C Problem Overview


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.

Objective C Solutions


Solution 1 - Objective C

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.

Solution 2 - Objective C

You can't pass a parameter in a @selector().

It looks like you're trying to implement a callback. The best way to do that would be something like this:

[object setCallbackObject:self withSelector:@selector(myMethod:)];

Then in your object's setCallbackObject:withSelector: method: you can call your callback method.

-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector {
    [anObject performSelector:selector];
}

Solution 3 - Objective C

Beyond what's been said already about selectors, you may want to look at the NSInvocation class.

> An NSInvocation is an Objective-C message rendered static, that is, it is an action turned into an object. NSInvocation objects are used to store and forward messages between objects and between applications, primarily by NSTimer objects and the distributed objects system. > > An NSInvocation object contains all the elements of an Objective-C message: a target, a selector, arguments, and the return value. Each of these elements can be set directly, and the return value is set automatically when the NSInvocation object is dispatched.

Keep in mind that while it's useful in certain situations, you don't use NSInvocation in a normal day of coding. If you're just trying to get two objects to talk to each other, consider defining an informal or formal delegate protocol, or passing a selector and target object as has already been mentioned.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBlueDolphinView Question on Stackoverflow
Solution 1 - Objective CJason CocoView Answer on Stackoverflow
Solution 2 - Objective CGrant LimbergView Answer on Stackoverflow
Solution 3 - Objective CMarc CharbonneauView Answer on Stackoverflow