2013-03-06 10 views
7

私は次のオブジェクトがある場合:私はコールする代わりにしようとするとObjective-C:オブジェクトをブロック引数として、その基本クラスが必要なメソッドに渡す方法はありますか?

[Test doSomething:^(Simple * obj) { 

}]; 

:私はのようなメソッドを呼び出す場合すべての作品

@interface Test : NSObject 

+(void) doSomething:(void (^)(Simple*)) obj; 

@end 

:よう

@interface Simple : NSObject 

@end 

@interface Complex : Simple 

@end 

そして、別のオブジェクトをそれは好きです:

[Test doSomething:^(Complex * obj) { 

}]; 
Simpleを拡張

Incompatible block pointer types sending 'void (^)(Complex *__strong)' to parameter of type 'void (^)(Simple *__strong)'

ので、私はこれは、Javaのように、働くだろうと思った:

コンパイラは、と言っています。

これをどうにかして実現する方法はありますか?

答えて

8

残念ながら、これはブロックAPIの制限です。あなたがブロックの引数のクラスを設定することができます

+(void) doSomething:(void (^)(id)) obj; 

:あなたがしたい場合は、完全に前述のタイプの安全性のオプションとしてブロックを宣言しています。しかし、再び、これは完全に安全でない、タイプワイズです。

+0

これは実際には残念ですか? 'Test'は、ブロックが' Simple '型の引数を取るという署名付きのブロックへの参照を求めて取得します。サブタイプ 'Complex'を取るブロックを渡すと、' Test'が 'Simple'の別のサブクラスでブロックを呼び出すことによって不正な呼び出しを行う可能性があります。 –

+0

私はこれを契約の違反と呼ぶのが合理的だと言っています。そうでない場合、コンパイラは、ブロックを実行するための 'Test'の呼び出しに正当なパラメータがあるかどうかを知ることができません。 –

+0

@SeamusCampbell申し訳ありませんが、私はあなたが書いたものを読んでいませんでした。はい、正確に。 – CodaFi

2

Complex *またはSimple *の代わりにidを使用してください。ブロックパラメータの型は、メソッドのパラメータ型とは異なります(@CodaFiありがとう)

関連する問題