2017-02-20 19 views
0

コンパイラがプロパティの割り当てを並べ替えることはないと仮定できますか?考えてみましょう以下:Objective-Cの順序が正しくない実行

@interface ObjA 
@property int x; 
@property int y; // When YES, x guaranteed to be set to 10. 
@end 

ObjA a; 
ObjB b; 

[a addObserver:b forKeyPath:@"y" options:nil context:&context] 
a.x = 10; 
a.y = YES; 

は、xがyの前に必ず割り当てられますか我々はメモリバリアを挿入する必要がありますか?

私はコンパイラがa.xの前にa.yを割り当てるのが安全であることを確かめるためにコンパイラが依存関係を調べるべきだと知っていますが、ここではすべてのオブザーバのすべての実装を見る必要があります。 ObjAがライブラリの一部である場合、リンク時間までこの情報を知ることさえできません。これは、並べ替えを行うには遅すぎる可能性がありますか?だから、コンパイラがプロパティの割り当てを並べ替えることは決してないと想定するのは安全でしょうか?イーバールはもちろん別の話です。

+4

私は現時点ではこれの直接のソースを提供することはできませんが、プロパティの割り当てを並べ替えることはできないと考えることができます。プロパティ構文はメソッド呼び出しの構文上の砂糖であり、Objective-Cは動的言語であるため、試してみるまでメソッド呼び出しが何をディスパッチするかを知ることは不可能です。したがって、メソッド呼び出しの順序を変更することはできません。コンパイラがそのような呼び出しを並べ替えた場合、ほぼ確実にバグになります。 –

+0

あなたが言及しているように、イーバルズは別の野球場です。 ivarにアクセスするとダイレクトメモリアクセスが行われるため、コンパイラはそれらを再編成することができます。 –

答えて

2

実行時にコードの動作が一定のままであることがわからないため、コンパイラはプロパティの割り当てを並べ替えることができません。

a.x = 10は、[a setX: 10]とまったく同じであり、したがって動的ディスパッチを行います。動的なので、コンパイル時に前記呼び出しの潜在的な副作用を知ることはできません。

ダイナミックディスパッチの瞬間は、コンパイラが実行を再注文できなくなった瞬間です。

+0

コンパイラがオブジェクトを解析するのに十分スマートではなく、動的なディスパッチがいくつかのメソッド呼び出しで必要かどうかを判断し、それらをインライン化してから並べ替えを行うのは確実でしょうか? –

+0

@JohnKはい。ある種の任意の時点で、間違ったコーダは、実行ファイルを非常に疑わしい方法で編集するコードを展開して、与えられた実行パスが実際に複雑になるようにすることがあります。 – bbum

関連する問題