148

MyClass.m で、定義しました

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

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

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

MyClass.m にあるが、次のようなエラーが表示 れる

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

4

8 に答える 8

315

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:);
于 2009-06-19T17:15:34.153 に答える
138

メソッドの署名は次のとおりです。

- (void) myTest:(NSString *)

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

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

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

それが動作します。

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

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

そして呼び出します:

[self performSelector:@selector(myTestWithAString:) withObject:myString];
于 2009-06-19T16:19:28.187 に答える
14

@シェーン・アーニー

performSelector:withObject:withObject:

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

Appleが送信するオブジェクトを2つしかサポートしておらず、より一般的にしていないのはちょっと奇妙です。

于 2012-11-05T13:10:38.330 に答える
7

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

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

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

メソッドを再定義して、コレクションを唯一のパラメーターとして受け取ることができます。

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

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

詳細が必要な場合は、コード例を含む記事を作成しました。スレッド化に重点が置かれていますが、基本は引き続き適用されます。

幸運を!

于 2009-07-18T15:19:26.487 に答える
3

あなたのメソッド シグネチャは意味がありません。間違いではありませんか? コンパイルがどうなっているのかはよくわかりませんが、無視しているという警告が出ているのではないでしょうか?

このメソッドが受け取るパラメータの数はいくつですか?

于 2009-06-19T14:24:29.620 に答える
2

クラスは次のように定義する必要があると考えてください。

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

パラメータは 1 つしかないため、次の 1 つだけを指定する必要があります。

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

于 2009-06-19T14:23:52.507 に答える