[英]Is there JavaScript apply like method in objective-c?
So basically I'm implementing the typical way to handle JavaScript calls in objc using window.location="myobj:mymethod:myarg:myotherarg", however, I'm wondering if there is a way to apply an array of arguments to a method, similar to how you can in JavaScript. 因此,基本上,我正在使用window.location =“ myobj:mymethod:myarg:myotherarg”实现在objc中处理JavaScript调用的典型方法,但是,我想知道是否有一种方法可以将参数数组应用于方法,类似于您在JavaScript中的操作方式。
Typically I've been doing 通常我一直在做
-(void) mymethod:(NSArray*) arr{
//method knows how many arguments it takes and what they mean at each index
}
I'd prefer to do: 我更愿意做:
-(void) mymethod:(NSString*) myarg myOtherArg: (NSString*) myotherarg{
//do stuff
}
and have a method like this: 并有这样的方法:
+(void) callMethod:(NSString*)selectorName withArgs: (NSArray*)args onObject:(id) obj{
//implementation
}
[JEHelpers callMethod:selector withArgs:someArrayOfArgs onObject:myapp]
is this possible? 这可能吗?
If you know that no method will take more than two arguments, you could use performSelector:withObject:withObject:
to do these calls. 如果您知道没有方法接受两个以上的参数,则可以使用
performSelector:withObject:withObject:
进行这些调用。 If the method takes less than two arguments, the unused withObject:
fields will be ignored. 如果该方法使用少于两个参数,则未使用的
withObject:
字段将被忽略。
+ (id)callMethod:(NSString *)selectorName withArgs:(NSArray *)args onObject:(id)obj {
id arg1 = nil, arg2 = nil;
if([args count]) {
arg1 = [args objectAtIndex:0];
if([args count] > 1])
arg2 = [args objectAtIndex:1];
}
return [obj performSelector:NSSelectorFromString(selectorName)
withObject:arg1 withObject:arg2];
}
If there could be more than two arguments, you will have to use NSInvocation
. 如果可能有两个以上的参数,则必须使用
NSInvocation
。 This class lets you construct a message by passing the various arguments and defining the selector and object, then send the message and get the result. 该类使您可以通过传递各种参数并定义选择器和对象来构造消息,然后发送消息并获取结果。
+ (id)callMethod:(NSString *)selectorName withArgs:(NSArray *)args onObject:(id)obj {
SEL sel = NSSelectorFromString(selectorName);
NSMethodSignature *signature = [obj methodSignatureForSelector:sel];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:sel];
[invocation setTarget:obj];
NSUInteger index = 2;
for(id arg in args) {
[invocation setArgument:&arg atIndex:index];
++index;
}
id result;
[invocation setReturnValue:&result];
[invocation invoke];
return result;
}
I'm not sure I entirely understand the question (I don't know JavaScript well). 我不确定我是否完全理解这个问题(我不太了解JavaScript)。 However, you can use NSInvocation to send arbitrary messages to any object.
但是,您可以使用NSInvocation将任意消息发送到任何对象。 Something like this:
像这样:
+(void) callMethod:(NSString*)selectorName withArgs: (NSArray*)args onObject:(id) obj
{
SEL selector = NSSelectorFromString(selectorName);
if (![obj respondsToSelector:selector]) {
// Object doesn't respond to selector, so do something else/handle the error
}
NSMethodSignature *methodSignature = [obj methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:obj];
[invocation setSelector:selector];
for (NSUInteger i=0; i<[args count]; i++) {
id argument = [args objectAtIndex:i];
[invocation setArgument:&argument atIndex:i+2]; // Arg 0 is self, arg 1 is _cmd
}
id result;
[invocation setReturnValue:&result];
[invocation invoke];
}
You might want to look into NSInvocation. 您可能需要研究NSInvocation。 Specifically, you want to build an NSInvocation with selectorName's method signature (NSObject -methodSignatureForSelector:), then set the selector, target, and arguments.
具体来说,您想使用选择器名称的方法签名(NSObject -methodSignatureForSelector :)构建一个NSInvocation,然后设置选择器,目标和参数。 Keep in mind: you should check for the argument types (NSMethodSignature -getArgumentTypeAtIndex:, is it equal to '@'), and the arguments you are passing are indexed starting with 2 (because 0 and 1 are the object's self and the method selector).
请记住:您应该检查参数类型(NSMethodSignature -getArgumentTypeAtIndex :,是否等于“ @”),并且将要传递的参数从2开始索引(因为0和1是对象的self和方法选择器)。
I'm not saying this is a good idea, btw; 我并不是说这是个好主意,顺便说一句; there are very few cases where this approach is warranted.
在极少数情况下,需要采用这种方法。
It's a bit clumsy but it is possible: 有点笨拙,但有可能:
- (id)method:(NSString *)arg1, ... {
va_list args;
va_start(args, arg1);
for (NSString *a = arg1; a!= nil; a= va_arg(args, NSString*)) {
// do stuff
}
}
Conventionally arg1
would be a string that defines the data types and number of extra parameters. 按照惯例,
arg1
是一个字符串,用于定义数据类型和额外参数的数量。
You'd call it like this: 您可以这样称呼它:
[self method:@"5", @"4", @"3", @"2", @"1"];
Your array method is probably clearer for most purposes. 对于大多数用途,您的数组方法可能更清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.