-1

検討:

[self.staves enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    HBStaffView * sv = (HBStaffView *) obj ;
    [sv flush] ;
}] ;

と:

[self.staves enumerateObjectsUsingBlock:^(HBStaffView * sv, NSUInteger idx, BOOL *stop) {
    [sv flush] ;
}] ;

どちらもコンパイルされ、両方が機能します。

私は列挙している配列の内容を知っているので、正しい型へのキャストがコンパイラーによって行われ、正しい型がどのように使用する必要があるかが明らかに恩恵を受けます。

しかし興味深いのは、ここで、ブロック署名はセレクターとは何の関係もない「C」言語の署名であり、オブジェクトについて (理論的には) 何も知らないということです。大雑把に話します)。

うーん?コメント?

4

3 に答える 3

4

2 つのコードに実質的な違いはありません。

このenumerateObjectsUsingBlock:メソッドは、ブロックの引数が であるパラメータとしてブロックを取ると宣言されています(id, NSUInteger, BOOL*)より具体的なオブジェクト型として宣言できるの(MyClass*, NSUInteger, BOOL*)は、Objective-C の機能です。より具体的な型が何らかの種類の Objective-C インスタンス参照である限り、より具体的な型指定子をパラメーターに置き換えることができます。id

ブロックが C 言語の機能であることは関係ありません。C 関数も同様ですが、C 関数にもオブジェクト型を渡すことができます。実際、Objective-C のメソッドは、常に先頭に 2 つの引数を持つ単なる C 関数です。 selfそして(任意の方法で_cmd試してください)。NSLog(@"%@", NSStringFromSelector(_cmd));

于 2013-05-17T16:02:31.223 に答える
2

構文は C 構文の場合がありますが、型idは Objective-C 型です。Objective-C としてではなく厳密な C としてコンパイルされたものでそのブロック署名を使用することはできませんでしたidvoid*

于 2013-05-17T16:09:21.383 に答える