web-dev-qa-db-ja.com

Objective-Cのセレクター?

まず、セレクターとは何かを本当に理解しているかどうかわかりません。私の理解では、これはメソッドの名前であり、「SEL」タイプのクラスに割り当ててから、respondToSelectorなどのメソッドを実行して、レシーバーがそのメソッドを実装しているかどうかを確認できます。誰かがより良い説明を提供できますか?

第二に、この時点で、次のコードがあります。

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

ただし、thingは明らかにNSStringの一種で、lowercaseStringに応答する必要がありますが、「YES」を返す条件付きの「respondsToSelector」を取得できません...

120
Craig

メソッド名には非常に注意する必要があります。この場合、メソッド名は「lowercaseString:」ではなく、単に「lowercaseString」です(コロンがないことに注意してください)。 NOオブジェクトはNSStringメッセージには応答しますが、lowercaseString:メッセージには応答しないため、lowercaseStringが返されます。

コロンを追加するタイミングはどのようにわかりますか?呼び出し時にコロンを追加する場合は、メッセージ名にコロンを追加します。これは、1つの引数を取る場合に発生します。引数がゼロの場合(lowercaseStringの場合のように)、コロンはありません。複数の引数を取る場合は、compare:options:range:locale:のように、余分な引数名とそのコロンを追加する必要があります。

documentation を見て、末尾のコロンの有無を確認することもできます。

177
Adam Rosenfield

セレクター は、コンパイルされたコードでメソッドを直接参照する効率的な方法です。コンパイラは、実際にSELに値を割り当てるものです。

他の人はすでにqの2番目の部分をカバーしています。末尾の「:」は、探しているものとは異なる署名に一致します(この場合、署名は存在しません)。

11
dstnbrkr

@selector(lowercaseString)ではなく、@selector(lowercaseString:)が必要だからです。微妙な違いがあります:2番目のパラメーターはパラメーターを意味します(末尾のコロンに注意してください)が、- [NSString lowercaseString]はパラメーターを取りません。

10
mipadi

この場合、セレクターの名前が間違っています。ここのコロンはメソッドシグネチャの一部です。メソッドが1つの引数を取ることを意味します。あなたが欲しいと思う

SEL sel = @selector(lowercaseString);
5
mkb

NSStringのメソッドは、lowercaseString:(1引数)ではなく、lowercaseString(0引数)です。

3
Nicholas Riley

コロンを関数名の一部と考えないでください。区切り文字と考えてください。分離するものがない場合(関数に値がない場合)、それは必要ありません。

なぜかはわかりませんが、OOのようなものはすべてApple開発者にとっては異質のようです。 Visual Studio Expressを入手して、それをいじってみることを強くお勧めします。一方が他方よりも優れているからではなく、単に設計の問題と考え方を見るのに良い方法です。

好む

introspection = reflection
+ before functions/properties = static
- = instance level

問題をさまざまな方法で見ることは常に良いことであり、プログラミングは究極のパズルです。

1
Roger Roger

Apple docs: https://developer.Apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

セレクターは、オブジェクトに対して実行するメソッドを選択するために使用される名前、またはソースコードのコンパイル時に名前を置き換える一意の識別子です。セレクター自体は何もしません。メソッドを識別するだけです。セレクターメソッド名をプレーンな文字列と異なるものにする唯一のことは、コンパイラーがセレクターが一意であることを確認することです。セレクターが便利なのは、(ランタイムと組み合わせて)動的関数ポインターのように機能し、指定された名前に対して、使用するクラスに適したメソッドの実装を自動的に指すことです。メソッド実行用のセレクターと、クラスDog、Athlete、およびComputerSimulation(それぞれがメソッド実行を実装している)があるとします。セレクターを各クラスのインスタンスで使用して、そのrunメソッドを呼び出すことができます(実装がそれぞれ異なる場合でも)。

例:(lldb)ブレークポイント--set selector viewDidLoad

これにより、アプリのすべてのviewDidLoad実装にブレークポイントが設定されます。そのため、セレクタはメソッドのグローバル識別子の一種です。

0
Adrian

Appleドキュメントの理解から、セレクターは、呼び出したいメソッドの名前を表します。セレクターの良いところは、呼び出される正確なメソッドが異なる場合に使用できることです。簡単な例として、次のようなことができます。

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];
0
moonman239