Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objective C using a string to call a method

Hi im new to objective C and was wondering if someone might be able to help me with this. I have a few different methods each requiring 3 input values and normally call it using

[self methodA:1 height:10 speed:3]

but the method name I want to read from a string in a plist so for example if the string was methodB i would get

[self methodB:1 height:10 speed:3] 

for "methodC"

[self methodC:1 height:10 speed:3]

and so on.

Any ideas how I might do this I tried defining the string as a Selector using NSSelectorFromString

NSString *string = [plistA objectForKey:@"method"];
SEL select = NSSelectorFromString(string);
[self performSelector:select:c height:b speed:a]; 

However this did not work either any help would be greatly appreciated. Have tried the solution below but could not get to work here is what i've tried.

So just to recap I have methods such as

 spawnEnemyA:2 withHeight:3 withSpeed:4  
 spawnEnemyB:3 withHeight:2 withSpeed:5 

and I want to read the values I want to pass to these methods as well as the method type from a plist file. my code is as follows, //////////////////////////////////////////////////////////////

//These are the values I read from the plist that I want my method to use

    int a = [[enemySettings objectForKey:@"speed"] intValue];
    int b = [[enemySettings objectForKey:@"position"] intValue];
    int c = [[enemySettings objectForKey:@"delay"] intValue];

   // I Also read the method name from the plist and combine it into a single string  
    NSString *method = [enemySettings objectForKey:@"enemytype"];
    NSString *label1 = @"spawn";
    NSString *label2 = @":withHeight:withSpeed:";
    NSString *combined = [NSString stringWithFormat:@"%@%@%@",label1, method,label2];


    //Check that the string is correct get spawnEnemyA:withHeight:withSpeed:
    CCLOG(@"%@",combined);


//This is the Invocation part 
    NSInvocation * invocation = [ NSInvocation new ];

    [ invocation setSelector: NSSelectorFromString(combined)];
    [ invocation setArgument: &c atIndex: 2 ];
    [ invocation setArgument: &b atIndex: 3 ];
    [ invocation setArgument: &a atIndex: 4 ];

    [ invocation invokeWithTarget:self ];

    [invocation release ];

////////////////////////////////////////////////////////////////////

The code compiles without any errors but the methods are not called. Any ideas? Cheers

like image 952
tomo Avatar asked Jun 20 '12 18:06

tomo


1 Answers

You can't use performSelector for a method with 3 (or more) arguments.
But for your information, here's how to use it:

SEL m1;
SEL m2;
SEL m3;

m1 = NSSelectorFromString( @"someMethodWithoutArg" );
m2 = NSSelectorFromString( @"someMethodWithAnArg:" );
m1 = NSSelectorFromString( @"someMethodWithAnArg:andAnotherOne:" );

[ someObject performSelector: m1 ];
[ someObject performSelector: m2 withObject: anArg ];
[ someObject performSelector: m2 withObject: anArg withObject: anOtherArg ];

For methods with more than 2 arguments, you will have to use the NSInvocation class.
Take a look at the documentation to learn how to use it.

Basically:

NSInvocation * invocation = [ NSInvocation new ];

[ invocation setSelector: NSStringFromSelector( @"methodWithArg1:arg2:arg3:" ) ];

// Argument 1 is at index 2, as there is self and _cmd before
[ invocation setArgument: &arg1 atIndex: 2 ];
[ invocation setArgument: &arg2 atIndex: 3 ];
[ invocation setArgument: &arg3 atIndex: 4 ];

[ invocation invokeWithTarget: targetObject ];

// If you need to get the return value
[ invocation getReturnValue: &someVar ];

[ invocation release ];
like image 56
Macmade Avatar answered Oct 20 '22 03:10

Macmade