2011-06-17 18 views
5

誰もこのブロック構文がどのように機能するか説明できますか?Objective-Cブロックの構文 - 誰かがこれを説明できますか?

AStreamBuilder stream_builder = [ [ ^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } copy ] autorelease ]; 
    return stream_builder; 

ブロックの名前は何ですか。ブロックがコピーされてからオートレリースされるのはなぜですか?私はここで何が起きているのか混乱しています。ブロックはAStreamBuilderを返すと言われていますが、ブロック本体の内部ではNSInputStreamのインスタンスを返します。

誰かがこれを打破できますか?

答えて

9

これはブロックである。

^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } 

それが任意のパラメータを受信して​​いない(したがって(void))、それはNSInputStreamのインスタンスを返します。

[[NSNumber alloc] initWithInt:42]; 

は、「名前」を持っていない、のいずれか:例えば、同じ意味で - それは「名前」を持っていないことに注意してください。

ブロックはスタック上に作成されるため、ブロックを返す必要がある場合はスタックからヒープにコピーする必要があります(したがって-copy)。これは所有オブジェクトです。発呼者が所有していないオブジェクトを返すために、ブロックは(それゆえ-autorelease)自動解放される:

[ [ ^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } copy ] autorelease ]; 

そこで、上記の抜粋は、ヒープにスタックからコピーされた自動解放ブロックです。それがAStreamBuilderはパラメータを受信しないとタイプNSInputStream(又はそれと互換性のあるタイプ)を返す有するブロックのtypedefである可能性が高いです可変

AStreamBuilder stream_builder = … 

に割り当てられます。 AStreamBuilderは、ブロックによって返される値の型とは対照的に、ブロック型であることに注意してください。ような何か:

typedef NSInputStream * (^AStreamBuilder)(void); 
0

ブロックをスタックからヒープに移動するためにブロックがコピーされています。これは、ブロックを作成するスコープ外のブロックを使用する場合に必要です。

4

は、ここではブロックの名前は何ですか?

新しいブロックは変数stream_builderに割り当てられます。ブロックが「anonymous inline collection of code

なぜブロックがコピーされてから自動リリースされるのかという理由で、名前自体はありません。

これは、現在のスコープ(メソッド/関数から返されている)の後に保持されるためです。したがって、copied to the heapである必要があります。

ブロックがAStreamBuilderを返すように言われているが、ブロックの本体内にはNSInputStreamのインスタンスを返す

あなたは(return stream_builder;で終わるもの)にいる関数/メソッドが返しますAStreamBuilder(=新しく作成されたブロック)。ブロック自体は、将来ある時点でinvokedとなったときにNSStreamを返します。

+0

ブロックがNSStreamのインスタンスを返す場合、どのように戻り値の型が上記の構文で宣言されていないのですか? – randombits

+1

これは、そこに表示される 'void'が戻り値ではなく引数であるためです。このブロックには引数はありません。戻り値の型はここでは何も指定されていません。 "[戻り値の型はオプションで、戻り値のステートメントから推測されます。](http://clang.llvm.org/docs/BlockLanguageSpec.txt)" – puzzle

+0

@randそこでは2つのことが起こっています。一方はパズルが言ったように、return型はreturn文から推論されます。一方、 'AStreamBuilder'は、ブロックの戻り値の型を定義する' typedef'です。代入が機能するためには、推定される戻り値の型は、 'AStreamBuilder'で定義された戻り値の型と一致しなければなりません。 Xcodeの 'AStreamBuilder'の宣言を右クリックし、定義にジャンプを選択することで調べることができます。 –

関連する問題