1

以下のコードを使用してアークをテストし、ARC を理解するのに役立ちます

NSArray __strong*  myArray = [NSArray arrayWithObjects:@"123", nil];
NSArray __weak*  yourArray = myArray;
NSArray __unsafe_unretained*  theirArray = yourArray;
myArray = nil;
NSLog(@"yourArray = %@, theirArray = %@", yourArray, theirArray);

私の理解では、ログは次のようになります: yourArray = (null), theirArray = (null) ログは次のとおりです: yourArray = ( 123 ), theirArray = ( 123 )

コードを変更して __unsafe_unretained を削除すると:

NSArray __strong*  myArray = [NSArray arrayWithObjects:@"123", nil];
NSArray __weak*  yourArray = myArray;
//NSArray __unsafe_unretained*  theirArray = yourArray;
myArray = nil;
NSLog(@"yourArray = %@", yourArray);

ログは正しいです:yourArray = (null)

__unsafe_unretained ローカル変数を追加して NSArray オブジェクトを弱参照すると、NSArray オブジェクトを保持または強化するようになるのはなぜですか。

誰でも疑問に答えることができます。

よろしくお願いします

4

2 に答える 2

2

コンパイラは、スコープが限定されたこの種の単純な例で、オブジェクトの有効期間を把握するのに非常に優れています。スコープの最後に到達するまで (または、少なくともこれらの単純な割り当てで最後の読み取りの最後に到達するまで)、配列を解放してはならないことがわかります。

とマークされた ivar を使用し、__unsafe_unretainedそれを弱い割り当ての後に割り当て、完全な最適化でビルドすると、この種の単純なケースであっても、異なる結果が表示される場合があります。__weakまた、基本的に、コンパイラーは、変数がまだ設定されていて、変数を災害​​なしで読み取ることができるこのような状況に対処できる場合がありますが、ポイントは、そのように動作することを期待__unsafe_unretainedできないということです。信頼できるのは、最後の参照がなくなった後に変数が nil になること、コンパイラが変数の保持/解放ディレクティブを挿入しないことです。__weak__strong__unsafe_unretained変数。ルールに従っている限り、予測可能な結果が得られます。ルールに従わないとすぐに、何が起こるか何が起こらないかが未定義になります... したがって、シミュレーターと iPod 4G では機能する可能性がありますが、4S と 5 では恐ろしく失敗し、iPad では半分の時間しか機能しません。 ..要点は、結果は未定義です。

于 2012-11-21T02:50:45.330 に答える
0

[NSArray arrayWithObjects:@ "123"、nil]によって返されるオブジェクトは自動解放され、自動解放プールがフラッシュされるまで割り当てが解除されません。オブジェクトの割り当てが解除されるまで、弱参照はゼロになりません。unsafe_unretained参照がゼロになることはなく、オブジェクトの割り当てが解除されると無効になります。

したがって、ログは

yourArray =(123)、theirArray =(123)

しかし、後でオブジェクトの割り当てが解除されると、次のようになります。

yourArray =(NULL)、theirArray = undefined

ポインタが無効であり、新しいオブジェクトまたは単なるガベージを指している可能性があるため、未定義です。コードがクラッシュする可能性もあります。

于 2012-11-21T02:55:04.330 に答える