5

My function looks like this

-(void) doTransition:(id)sender withID:(int) n

How do I pass int n to selector,

target:self selector:@selector(doTransition:)withID:3

this won't work

Please help Thanks

Brandon Buck
  • 7,177
  • 2
  • 30
  • 51
user2735868
  • 83
  • 1
  • 1
  • 4
  • you can send NSDictionary instance with all attributes that you need :) Then your function will look like `-doTransition:(NSDictionary*)info` – Neil Galiaskarov Nov 11 '13 at 15:59

4 Answers4

6

So, I Googled "calling selectors with arguments" and got a bunch of results, the first of which is a question here on SO: Objective-C: Calling selectors with multiple arguments

The most voted answer there has some details, specifically:

[selectorTarget performSelector:mySelector withObject:@3];

This is a simple task to perform. More information can be found at the linked question/answer area.

Notice the @3 I passed, which is not an int but an NSNumber. If you have an int value you can easily get an NSNumber by performing [NSNumber numberWithInt:myIntValue]. The @3 is shorthand syntax available in clang 3.4 for creating an NSNumber with an integer value. The use of NSNumber here instead of int is important because this selector call expects an id type as the withObject: parameter and so thus I need an object, and not a primitive type (whether the compiler auto-wraps for you, I can't say).

Another important note is that there are three performSelector: functions defined:

- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)anObject;
- (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject;

So you can see you can use functions that don't take values and functions that take one or two values as selectors but outside of that you'd most likely need to write your own logic for calling functions with greater than 2 arity.

Community
  • 1
  • 1
Brandon Buck
  • 7,177
  • 2
  • 30
  • 51
  • Instead of "write your own logic for calling functions" you can also use NSInvocation to call a selector with more than 2 parameters or for a selector which returns something. – Geraud.ch Nov 11 '13 at 16:13
  • @Geraud.ch Correct me if I'm wrong but wouldn't that qualify as "writing your own logic?" This means that you use whatever tools you have that allow you to do so, but it's not something that is available for you attached to an Object like the `performSelector:` functions. – Brandon Buck Nov 11 '13 at 16:15
  • I thought you would like to say: wrap your method with arguments in another method so that you can use the same performSelector. The goal was to add a pointer to NSInvocation, not to disagree with you :) – Geraud.ch Nov 11 '13 at 16:18
  • @Geraud.ch Ah, I gotcha. To be honest, I'm not really familiar enough with `NSInvocation` to offer that out as advice, and I only refrain from mentioning it because it's been mentioned in comments and another answer as well. Although it is a good point of research. – Brandon Buck Nov 11 '13 at 16:20
  • Thanks, that's helpful – user2735868 Nov 11 '13 at 17:40
  • @izuriel, it looks like you and I posted pretty much the same answer within a short time of each other. I suspect you posted yours while I was composing mine. – Duncan C Nov 27 '13 at 04:50
  • @DuncanC It happens a lot, I did up vote your answer. – Brandon Buck Nov 27 '13 at 05:05
5

The short answer is that you don't. methods like performSelector: are set up to pass NSObjects as parameters, not scalar values.

There is a method performSelector:withObject:withObject: that will invoke a method with 2 object parameters.

You can trigger a method with any type of parameters by creating an NSInvocation, but it's a fair amount of work, and a little tricky to figure out how to do it.

In your case it would be simpler to refactor your method to take the ID parameter as an NSNumber object.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
0

It not easy to use NSNumber to pass value, I implemented a method to pass an object as int.

+ (void)showNotice:(NSString *)str atView:(UIView *)view delay:(int)delay {
    [cc_message cc_instance:CC_Notice.shared method:@selector(showNotice:atView:delay:) params:str,view,Int(delay)];
}

And use invocation to receive and reduction to int.

CC_Int *ccint = (CC_Int *)obj;
int value = ccint.value;
[invocation setArgument:&value atIndex:i+2];
Gao
  • 85
  • 1
  • 7
  • this also resolved performSelector: can only pass 2 (as max) objects. It can pass object as many as you want. – Gao Sep 12 '19 at 03:38
-1

You need to pass a NSDictionary with the values you want to send, something like:

NSDictionary *myDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:3] forKey:@"myInt"];
Antonio MG
  • 20,382
  • 3
  • 43
  • 62
  • 1
    I don't see how wrapping the value inside of a dictionary solves the question in "How do I pass this value to a selector?" where there is no code demonstrating that the person is aware of the functions needed to pass objects. – Brandon Buck Nov 11 '13 at 16:14