2016-08-25 26 views
1

キーワード「ブロック」と「自己」が出てきたすべてのスレッドは、サイクルを保持するためのものです。しかし、それはここで問題ではありません...Objective-Cブロックと自分自身をキャプチャ

私の質問は:なぜブロック外のselfのプロパティに加えられた変更がブロック内に表示されますか?私は価値観が「捕らえられる」と考えていましたか?つまり、ブロックが参照するのは元のオブジェクトのコピーです。ここで

が私のジレンマを説明するためのコードのビットです:

int a = 1; 
self.someProperty.name = @"Foo"; 

[self.someProperty someMethodWithCompletionHandler:^() { 
    NSLog(@"%d", a); 
    NSLog(@"%@", self.someProperty.name); 
}]; 

a = 2; 
self.someProperty.name = @"Bar"; 

私が手出力は次のようになります。

1 
Bar 

答えて

2

値がキャプチャされaはブロック内1である理由、それはです。

あなたの文字列はオブジェクトです。ポインタ(実際にはアドレス)はキャプチャされますが、ポインタが指している文字列の値が変更されています。だからあなたは "バー"を見るのです。

+0

ああ、そうです。だから、 '*'や '&'のようにObjective-Cのポインタを細かく制御しているわけではないので、ブロック内でアクセスされるオブジェクトはすべて参照によって行われますか? – Ash

+2

オブジェクトは参照渡しされません。むしろ、オブジェクトへの参照が渡されます。これは微妙で重要な違いです。 – Avi

+0

ご清聴ありがとうございます。これによりObjective-CはC++よりもJavaに似ているように見えます。 – Ash

2

C、および拡張として、Objective-Cはバイ・セマンティクスを使用します。つまり、関数にパラメータを渡すと、変数の値のコピーが呼び出し先に渡されます。呼び出し先がコピーされた元の変数を変更できるようにする方法は、ポインタを渡すことです。呼び出し先は、元の変数によって参照されるメモリ位置に直接アクセスする方法を提供します。

int a = 1; // a is stored at memory location 0xABCD 

f(a); // The value of a (1) is passed to f(). This copy is at 0xCDEF. 

void f(int a) { 
    // The value at 0xCDEF is now 10, but 0xABCD (the "original") is untouched. 
    a = 10; 
} 

g(&a); // The address of "a" is passed. This is the value 0xABCD. 

void g(int *a) { 
    // This dereferences the pointer and changes the value at that location to 10. 
    // As the value of the pointer is the address of "a", the original variable "a" 
    // now has the new value of 10. 
    *a = 10; 
} 

Objective-Cのブロックは同じように動作します。取得された値は、関数にパラメーターとして渡されたものと同じ種類です。つまり、ポインタを渡すと元の変数は変更されず、ポインタを渡すとその場所のメモリが変更されます。オブジェクトはポインタを介してのみアクセスできるため、すべてのオブジェクト変数はポインタです。これにより、ブロックは上記の例のg()と同じ方法でオブジェクトを操作することができ、 "元の" a変数を操作できます。

+0

偉大な答え:) –

+0

次のリーダではっきりさせるために、 'g()'の引数に別の変数名を使用してください(したがって、続くコメントを更新してください)。私はあなたが言っていることを得る。 'int new_a = 2;のような行を追加すると助けになるかもしれません。 a = &new_a; 'は、Cでポインタがどのように変化するのかを示すために、Objective-Cでは使用できない機能と同じ値を保持します。 – Ash

+0

'g()'に別の変数を使用すると、同じ変数をさまざまな方法で処理して異なる効果を得ることができるという点が欠落します。そして、ObjCでは利用できないC言語の機能はないので、2番目のリクエストについては何も分かりません。 – Avi

関連する問題