2010-11-28 4 views
14

私はクラスiphone - performSelector:withObject:afterDelay: 'プロトコルに見つかりませんでしたか? '-performSelector:withObject:afterDelay:'

[delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 

と、私はこのエラー

警告を持っています内側にこれを持っているが、プロトコル(複数可)

には見られない

何が間違っているかわかりません。

手がかりはありますか?

ありがとうございました。

[(SomeClass *) delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 

は、あなたのdelegateがタイプidであると仮定すると、あなたが実際にオブジェクトがNSObjectから継承しない実行時に指示する必要があります:

答えて

30

あなたの問題は、あなたのようにあなたのデリゲートインスタンス変数を宣言したことであることを試してみてください。

id<SomeProtocol> delegate; 

右?つまり、コンパイル時のチェッカーは、<SomeProtocol>プロトコルのメソッドを探すだけです。ただし、performSelector:withObject:afterDelay:NSObjectで宣言されています。これは、それが<SomeProtocol>に準拠して任意のオブジェクトとは反対に、<SomeProtocol>に準拠NSObjectでなければならないと言っている

NSObject<SomeProtocol> * delegate; 

:これはあなたのようにIVARを宣言する必要があることを意味します。これはあなたの警告を取り除くはずです。キャストをする必要はありません。

+1

パーフェクト!それでおしまい!!!!!! – SpaceDog

+0

@Dave私はおそらくObjective-Cのことを他の誰よりもあなたからもっと知りました!ありがとう! –

+1

@Jacobあなたは大歓迎です:) –

3

はまず、その後、performSelector:withObject:afterDelayを呼び出し、そのクラスの型にデリゲートをキャストしてみ(performSelector:withObject:afterDelay:メソッドが定義されているところ)をクラスの型にキャストします。

+1

オブジェクトは常にNSObjectから継承されます(すべてがそうです、それはルートクラスです)。 NSObjectプロトコルに準拠していると思います。 –

+1

@EvanすべてはNSObjectから継承しません。 'performObject:afterObject:afterDelay:'は 'NSObject'プロトコルで定義されていません。NSObject'クラスで定義されています。 –

+1

キャスティングがカプセル化を中断します。デリゲートのタイプが不明なクラスの場合はどうなりますか? –

2

デリゲートオブジェクトを、実際のクラスにキャストして、メソッドを持たせる必要があります。デリゲートが見たのは、プロトコルで定義されているメソッドのみを表示できることです。 performSelector:withObject:はプロトコルで定義されたメソッドではありません。

[(CLASS*)delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 
1
[NSTimer scheduledTimerWithTimeInterval:2 
    target:self 
    selector:@selector(doStuff) 
    userInfo:nil 
    repeats:NO]; 

あなただけのタイマーをしたいと仮定し

3

Daveがキャストしたキャストは機能しますが、人々が期待どおりにプロトコルを使用できるように、よりクリーンな代替方法があります。プロトコル自体がNSObjectプロトコルをサポートすることを宣言することができます。

NSObjectは単なる実装ではなく、すべてのperformSelector:メソッドの変形を含むプロトコルです。

@protocol MyProtocol <NSObject> 

およびコンパイラの警告は(あなたは、プロトコルの定義をインポートしていると仮定すると)消える:だから、あなたは、単に他のクラスがプロトコルをサポートしているでしょうあなたはあなたのようなNSObjectのをサポートする、あなたのプロトコルに宣言することができます。

これは、あなたのプロトコルのサポートを宣言している人は、NSObjectでなければならないか、あるいは多くのメソッドを継承しなければならないことに注意してください。しかし、iPhoneプログラミングで使用されるすべてのクラスは、実際の考慮事項のためにNSObjectから派生しているため、一般的には問題にはなりません。

EDIT:

それは-performSelector:withObject:afterDelay:は、NSObjectのプロトコル(遅延なしのものである)ではありませんが判明しました。プロトコルタイプを参照するためにidを使用することができるのであれば、あなたのプロトコルを使用するすべての人にとってまだ良いので、これを解決するためにプロトコルを使用しますが、自分でNSObjectプロトコルの拡張を宣言する必要があります。あなたのファイルのヘッダーには次のようなものを追加することができます:

@protocol MyProtocolNSObjectExtras <NSObject> 
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay; 
@end 

@protocol MyProtocol <NSObjectExtras> 
.... 
@end 

これまで説明したのと同じ利点があります。

+0

問題のメソッドが ''ではなく 'NSObject'で定義されているので、この場合(これは試してみました)、これはうまくいかないでしょう。 –

+0

Aha、私はあなたが何を意味しているのか見ています - プロトコルがperformSelector:withObjectをサポートしているのを見て、afterDelay:ar私はまだプロトコルを使用しますが、私は答えを修正します。 –

関連する問題