2

でセレクターのIDを取得する場合@selector()、引数の型によってセレクターの値が違うのですか?

これが私の言いたいことです。オブジェクト参照とセレクターを受け取り、パラメーターを使用して呼び出すメソッドがあります。

-(void)CallLater:(NSObject*) Obj Sel: (SEL)Sel
{
    //Some stuff, then:
    [Obj performSelector: Sel withObject: SomeOtherObject];
}

ではなく、型指定されたオブジェクト参照を取る関数へのセレクターでこのメソッドを使用していますid

-(void)MyMethod: (MyObject*) a
{
}

[self CallLater: self Sel:@selector(MyMethod:)];

効いているように見えますが、私の感覚はチクチクしています。C# のような静的に型付けされた言語では、これはファウル、アップキャストにCallLaterなりidますMyObject

一方、コンパイラは文句を言わずid、具体的なオブジェクト参照の両方が、深いところにある単なるポインターのように見え、お互いに簡単にキャストできます。繰り返しますが、Objective C コンパイラが文句を言わない多くのファウルがあります。

本当の問題は、それは安全か?ということです。語学弁護士歓迎。

4

1 に答える 1

3

安全です; オブジェクトはオブジェクトです。のセレクタ パラメータは、 のセレクタ パラメータNSObject *とまったく同じMyObject *です。

MyMethod が特定のタイプのオブジェクトで呼び出されていることを確認する場合は、それに対して NSParameterAssert を実行する必要があります。

NSParameterAssert([obj isKindOfClass: [MyObject class]]);

個人的に、私はめったにこのチェックをしません。実際のオブジェクトが希望するタイプのように動作するだけで十分です。そうでない場合は、実行時エラー (通常は認識されないセレクター) が発生します。単純なケースではコンパイラの警告が表示されますが、この警告に注意を払う価値があります (必要に応じて id キャストで警告を無効にします)。

私はあなたの質問でのあなたの使用についてここで少し混乱しているので、あなたがこれを理解してidいることを確認したい. はジェネリック インスタンス ポインター クラスですが、 はインスタンス (または のサブクラス) です。の子孫ではないオブジェクトを持つことができます。しかし、これを知る必要はまずありません。NSObject *idMyObject *idNSObject *NSObjectNSObjectNSObject

その他の注意事項、re: 規則:

  • CallLater:Sel:セレクター (名前とパラメーターの両方)は小文字で始まるため、callLater:sel:.
  • 変数名とパラメーター名は小文字で始まります。Obj以上でお願い致しますobj
  • クラス名は大文字で始まります。:)
于 2012-07-20T01:55:12.173 に答える