objective C使用字符串来调用方法

tom*_*omo 5 string methods objective-c plist

嗨,我是目标C的新手,想知道是否有人可以帮我这个.我有几个不同的方法,每个方法需要3个输入值,通常使用它来调用它

[self methodA:1 height:10 speed:3]
Run Code Online (Sandbox Code Playgroud)

但是我想从plist中的字符串中读取方法名称,例如,如果字符串是methodB我会得到

[self methodB:1 height:10 speed:3] 
Run Code Online (Sandbox Code Playgroud)

为"methodC"

[self methodC:1 height:10 speed:3]
Run Code Online (Sandbox Code Playgroud)

等等.

任何想法如何我这样做我尝试使用NSSelectorFromString将字符串定义为选择器

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

然而,这不起作用任何帮助将不胜感激.尝试了下面的解决方案,但无法在这里工作是我尝试过的.

所以我只想回顾一下我的方法

 spawnEnemyA:2 withHeight:3 withSpeed:4  
 spawnEnemyB:3 withHeight:2 withSpeed:5 
Run Code Online (Sandbox Code Playgroud)

我想读取我想传递给这些方法的值以及plist文件中的方法类型.我的代码如下,//////////////////////////////////////////// //////////////////

//这些是我从plist中读取的值,我希望我的方法可以使用

    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 ];
Run Code Online (Sandbox Code Playgroud)

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

代码编译没有任何错误,但不调用方法.有任何想法吗?干杯

Mac*_*ade 11

您不能使用performSelector具有3个(或更多)参数的方法.
但是对于您的信息,以下是如何使用它:

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 ];
Run Code Online (Sandbox Code Playgroud)

对于具有2个以上参数的方法,您必须使用NSInvocation.
查看文档以了解如何使用它.

基本上:

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 ];
Run Code Online (Sandbox Code Playgroud)

  • 我看到了一个空间的粉丝.:)这也是可行的.对于这样的调用,我更喜欢用于速度的转换`objc_msgSend()`,最重要的是,类型安全,因为如果我稍后搞砸类型,编译器会抱怨. (3认同)

Jac*_*ack 1

您可以直接使用objc_msgsend

NSString *methodName = [plistA objectForKey:@"method"];
objc_msgSend(self, methodName, c, b, a);
Run Code Online (Sandbox Code Playgroud)

请注意,选择器必须包含所有部分,例如@"method:height:speed:"