0

このメソッドを使用してスーパービューを閉じようとしています[self.superview buttonPressedClose];

私はすでにスーパービューにそのメソッドを実装しており、すべてが機能しています。

しかし、コンパイル中に「UIView may not response to 'buttonPressedClose'」というアラートが表示されます。

次の行に変更すると、アラートは表示されませんが、これは正しい方法ですか?

if ([self.superview respondsToSelector:@selector(buttonPressedClose)]) {
    [self.superview performSelector:@selector(buttonPressedClose) withObject:nil afterDelay:0.0];
}

ありがとう。

**編集されたタイプミス..

4

2 に答える 2

4

これは問題のタイプミスですか、それともあなたのコードですか?

if ([self.superview respondsToSelector:@selector(buttonPressedClose)]) {
                                                   //  vv here
[self.superview performSelector:@selector(buttonPressedCLose) withObject:nil afterDelay:0.0];
}

一般に、self.superviewタイプのオブジェクトを返しますUIView。 yourbuttonPressedCloseは、 に実装されていないカスタム セレクターですUIView。そのため、警告が表示されます。

self.superview目的のタイプにキャストすることもできます。たとえば、次のようになります。

[(MyView *)self.superview buttonPressedClose];

またはそれをさらに神秘的にしてキャストしますid-コンパイラーはセレクターの存在をチェックしません:

[(id)self.superview buttonPressedClose];

とはいえ、上記のソリューションはすべて少し臭いです。

ゼロ遅延に関する非常に重要な点の 1 つperformSelector:は、セレクターをその場で実行するのではなく、セレクターの実行をスレッドの実行ループにポストし、制御が実行ループに戻ったとき (つまり、呼び出しスタックが空になったとき) に実行することです。したがって、通常の状況では、使用したくないでしょう。

于 2011-10-15T17:42:03.577 に答える
0

「これは正しい方法ですか?」

いいえ、このようにする理由はありません。afterDelay:0すぐに実行したくない場合にのみ使用されます。すぐに実行したい場合は、performSelector:なしで使用する必要がありますafterDelay:

しかし、performSelector:このように直接使用してもメリットはありません。これは、メソッドを直接呼び出すのと同じですが、より複雑な方法です。表示される警告は、純粋に静的型チェックの問題です。型 ( UIView *) がそのメソッドを持つことは保証されていません。メソッドをサポートする予想されるビュー タイプにキャストするidか、メソッドのチェックをオフにするためにキャストする必要があります。を使用performSelector:すると、メソッドの静的型チェックも回避されるため、キャストしてからid呼び出すよりも厳密には優れていません。

于 2012-01-25T03:48:08.700 に答える