5

したがって、基本的には、window.location = "myobj:mymethod:myarg:myotherarg"を使用してobjcでJavaScript呼び出しを処理する一般的な方法を実装していますが、引数の配列をメソッドに適用する方法があるかどうか疑問に思っています。 、JavaScriptでできる方法と同様です。

通常、私はやっています

-(void) mymethod:(NSArray*) arr{
    //method knows how many arguments it takes and what they mean at each index
}

私はしたい:

-(void) mymethod:(NSString*) myarg myOtherArg: (NSString*) myotherarg{
    //do stuff
}

次のような方法があります。

+(void) callMethod:(NSString*)selectorName withArgs: (NSArray*)args onObject:(id) obj{
    //implementation
}
[JEHelpers callMethod:selector withArgs:someArrayOfArgs onObject:myapp]

これは可能ですか?

4

4 に答える 4

2

2つ以上の引数を取るメソッドがないことがわかっている場合は、performSelector:withObject:withObject:これらの呼び出しを行うために使用できます。メソッドが2つ未満の引数を取る場合、未使用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];
}

3つ以上の引数が存在する可能性がある場合は、を使用する必要がありますNSInvocation。このクラスでは、さまざまな引数を渡し、セレクターとオブジェクトを定義してメッセージを作成し、メッセージを送信して結果を取得できます。

+ (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;
}
于 2012-05-11T15:07:08.673 に答える
2

質問を完全に理解しているかどうかはわかりません(JavaScriptについてはよくわかりません)。ただし、NSInvocationを使用して、任意のメッセージを任意のオブジェクトに送信できます。このようなもの:

+(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];
}
于 2012-05-11T15:12:38.190 に答える
1

NSInvocationを調べることをお勧めします。具体的には、selectorNameのメソッドシグネチャ(NSObject -methodSignatureForSelector :)を使用してNSInvocationを作成し、セレクター、ターゲット、および引数を設定します。覚えておいてください:引数のタイプをチェックする必要があり(NSMethodSignature -getArgumentTypeAtIndex :、それは'@'と等しいですか)、渡す引数は2から始まるインデックスが付けられます(0と1はオブジェクトの自己とメソッドセレクターであるため) )。

ところで、これが良い考えだと言っているのではありません。このアプローチが正当化されるケースはほとんどありません。

于 2012-05-11T15:13:49.080 に答える
0

それは少し不器用ですが、それは可能です:

- (id)method:(NSString *)arg1, ... {
  va_list args;
  va_start(args, arg1);
  for (NSString *a = arg1; a!= nil; a= va_arg(args, NSString*)) {
    // do stuff
  }
}

従来arg1は、データ型と追加パラメータの数を定義する文字列でした。

あなたはそれをこのように呼ぶでしょう:

[self method:@"5", @"4", @"3", @"2", @"1"];

配列メソッドは、ほとんどの目的でおそらくより明確です。

于 2012-05-11T15:22:30.083 に答える