Objective-C:複数の引数を持つセレクターの呼び出し


142

MyClass.mで、私は定義しました

- (void) myTest: (NSString *) withAString{
    NSLog(@"hi, %@", withAString);
}

MyClass.hの適切な宣言。後で電話したい

[self performSelector:@selector(mytest:withAString:) withObject: mystring];

MyClass.mでエラーが発生しますが、 *キャッチされない例外 'NSInvalidArgumentException'によりアプリを終了しています。理由: '* -[MyClass myTest:withAtring:]:認識されないセレクターがインスタンス0xe421f0に送信されました'

文字列をコンソールに出力する引数をとらず、うまく機能するセレクターを使用して、より簡単なケースを試しました。コードの何が問題になっていて、どうすれば修正できますか?ありがとう。


4
あなたの投稿は「複数の引数」について尋ねていますが、使用するのは1つだけです。今、私は誰かが複数の引数を使ってそれをどのように行うかについて興味があります。
RonLugge

回答:


137

メソッドシグネチャは次のとおりです。

- (void) myTest:(NSString *)

withAStringはたまたまパラメーターです(名前は誤解を招くようです。セレクターの署名の一部のようです)。

この方法で関数を呼び出す場合:

[self performSelector:@selector(myTest:) withObject:myString];

それが動作します。

ただし、他の投稿者が示唆しているように、メソッドの名前を変更することをお勧めします。

- (void)myTestWithAString:(NSString*)aString;

そして電話:

[self performSelector:@selector(myTestWithAString:) withObject:myString];

2
人々がこの回答から恩恵を受けていることを確認したので、私は私の回答を見直しました。呼び出しは単純にすることをお勧めします:-(void)testWithString:(NSString *)aString;
リンジーファーガソン

313

Objective-Cでは、セレクターのシグネチャは次のもので構成されます。

  1. メソッドの名前(この場合は 'myTest'です)(必須)
  2. メソッドに入力がある場合、メソッド名に続く ':'(コロン)。
  3. 追加の入力ごとに名前と「:」。

セレクターは次のことを認識していません。

  1. 入力タイプ
  2. メソッドの戻りタイプ。

次に、performMethodsViaSelectorsメソッドがセレクターを介して他のクラスメソッドを実行するクラス実装を示します。

@implementation ClassForSelectors
- (void) fooNoInputs {
    NSLog(@"Does nothing");
}
- (void) fooOneIput:(NSString*) first {
    NSLog(@"Logs %@", first);
}
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
    NSLog(@"Logs %@ then %@", first, second);
}
- (void) performMethodsViaSelectors {
    [self performSelector:@selector(fooNoInputs)];
    [self performSelector:@selector(fooOneInput:) withObject:@"first"];
    [self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];
}
@end

セレクタを作成するメソッドには単一の入力があるため、次のようにセレクタを作成します。

SEL myTestSelector = @selector(myTest:);

3
いい答えだ。少し明確にするために、セレクター名には少なくとも1つの部分が必要であり、パラメーターを受け取る場合と受け取らない場合があります。その場合、コロンが必要です。2つ以上の部分を持つセレクター名では、各部分の後にコロンを付ける必要があります。「-useFoo:andBar:toDoSomething」形式のセレクターを使用することは不正です。
クインテイラー、

これをありがとう。私はしばらくこれに苦労していました、助けてくれてうれしいです!
ジェームズホール

入力パラメータは整数ですか?この場合はどうしますか?
ホアンファム

1
整数をNSNumberオブジェクトでラップし(developer.apple.com/library/ios/#documentation/Cocoa/Reference/…を参照)、呼び出されたメソッドの本体で整数値を取得する必要があります。それは少し冗長かもしれません(そして私はそれを回避するより良い方法を見つけていません)が、それは正常に動作します。
シェーンアーニー

30
+100:これはすごい!複数の「withObject:」パラメーターを使用できることを知りませんでした。できればこれを100回
賛成し

13

@Shane Arney

performSelector:withObject:withObject:

また、このメソッドは最大2つの引数を渡すためのものであり、遅延させることはできません。(などperformSelector:withObject:afterDelay:)

ちょっと奇妙なことに、Appleは送信する2つのオブジェクトしかサポートせず、それをより一般的なものにしませんでした。


2
情報をありがとう。私は遅れをとることができなかった、そして今や私はその理由を知っている。参考までに、2つのオブジェクトの制限を回避するために、配列を渡してメソッドで使用しました。
JScarry 2015年

7

コードには2つの問題があります。1つは識別されて回答されましたが、もう1つは確認されませんでした。1つ目は、セレクターにパラメーターの名前がないことです。ただし、それを修正しても、変更されたメソッドシグネチャにまだ複数の引数が含まれていると想定すると、この行では例外が発生します。変更したメソッドが次のように宣言されているとします。

-(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ;

複数の引数を取るメソッドのセレクターの作成は完全に有効です(例:@selector(myTestWithString:comparedTo :))。ただし、performSelectorメソッドでは、1つの値しかmyTestに渡すことができませんが、残念ながら複数のパラメーターがあります。エラーが発生し、十分な値を指定しなかったことが通知されます。

唯一のパラメーターであるため、コレクションを取得するようにメソッドをいつでも再定義できます。

-(void)myTestWithObjects:(NSDictionary *)testObjects ;

ただし、より洗練されたソリューションがあります(リファクタリングを必要としません)。その答えは、そのとともに、NSInvocationを使用することですsetArgument:atIndex:し、invoke方法。

詳細が必要な場合は、コード例を含めて記事を書きまし。スレッドに焦点を当てていますが、基本はまだ適用されます。

幸運を!


3

メソッドのシグネチャは意味がありません。タイプミスではありませんか?どのようにコンパイルされているかはわかりませんが、おそらく無視しているという警告が表示されますか?

このメソッドが取るパラメータはいくつあると思いますか?


申し訳ありません。私はそれをタイプアウトして、コードをコピーして貼り付けるのではなく、もっと簡単にしようとしましたが、プロセスを間違えました。このメソッドは1つのパラメーターを受け取ることを期待しています。印刷したい文字列。
Stu

2

クラスを次のように定義する必要があると考えます。

- (void) myTestWithSomeString:(NSString *) astring{
    NSLog(@"hi, %s", astring);
}

パラメータは1つしかないので、1つだけにする必要があります。

NSLogで%@を使用することを検討することもできます。これは、取得するのは良い習慣です。文字列だけでなく、オブジェクトを書き出します。


-1

iOSユーザーも自動大文字化を期待します。標準のテキストフィールドでは、大文字と小文字が区別される言語の文の最初の文字が自動的に大文字になります。

そのような機能を実装するかどうかを決定できます。上記の機能のいずれにも専用のAPIはないため、それらを提供することは競争上の利点です。

Appleのドキュメントでは、この機能に使用できるAPIはなく、カスタムキーボードには他に期待される機能もあるとしています。これを実装するには、独自のロジックを見つける必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.