4

次のように、配列を列挙するときにオブジェクトを「nil」に設定したいと思います。

for(Object* object in array){
    object = nil;
}

Xcode は、「高速列挙変数は、デフォルトでは ARC で変更できません。これを許可するには、変数 __strong を宣言してください。

これは、次のことを意味します。

for(Object __strong* object in array){
    object = nil;
}

これは冗長なようです。私が理解している限り、オブジェクトへの強い参照を宣言すると、その保持カウントが 1 増加し、それを nil すると保持カウントが 1 減少します。nilでは、配列を列挙するときにオブジェクトを設定するにはどうすればよいでしょうか。

ARCを使用しています。

4

3 に答える 3

3

Clangの「Objective-C自動参照カウント」ドキュメントの高速列挙反復変数を参照してください。

変数がObjective-C高速列挙ループの条件で宣言され、変数に明示的な所有権修飾子がない場合、変数はで修飾const __strongされ、列挙中に検出されたオブジェクトは実際には保持されません

理論的根拠
これは、高速列挙ループが列挙中にオブジェクトを保持することを約束し、コレクション自体を同期的に変更できないために可能になった最適化です。変数を明示的に修飾することでオーバーライドできます。これにより__strong、変数が再び可変になり、ループで遭遇したオブジェクトが保持されます。

したがって、デフォルトでは、ループ変数は不変であり、パフォーマンス上の理由から、現在のオブジェクトの保持カウントは増加しません。

ループ変数を明示的に宣言すると__strong、それは可変の強力な参照であり、現在のオブジェクトの保持カウントが増加し、ループ変数を設定nilして保持カウントを再び減少させます。ただし、配列はオブジェクトへの別の強力な参照を保持しているため、そうしてもオブジェクトの割り当てが解除されたり、配列から削除されたりすることはありません。

于 2013-01-08T06:11:18.063 に答える
2

ショートカット:

[array removeAllObjects];

配列にx個のアイテムを含めたいが、現在その中にあるアイテムだけを含めたくない場合は、NSNullプレースホルダーを使用できます。

for (NSUInteger i = 0; i < [array count]; i++)
    [array replaceObjectAtIndex:i withObject:[NSNull null]];

配列はそのオブジェクトへの参照のみを保持することに注意してください。配列がオブジェクトへの参照を保持しなくなった場合(ただし、他にオブジェクトへの参照が保持されていない場合のみ)、メモリ管理が開始され、オブジェクトの割り当てが解除されます。

于 2013-01-08T06:15:02.707 に答える
0

コメントで、ここでの意図は、他の何かが所有権を主張しているかどうかに関係なく、配列内にあるオブジェクトの割り当てを解除することであることを明らかにしました。これはコア メモリ管理の原則に違反しています。所有していないメモリを解放してはなりません。やりたいことをやるのは悪い考えです。

他のオブジェクトが独自のメモリを管理できるようにする必要があります。おそらく、配列内の項目の 1 つは、UI オブジェクトが表示しているデータの一部です。UI オブジェクトがそれ自体を更新する必要があり、割り当てが解除されたデータをその下から探すと、アプリケーションがクラッシュする可能性があります。

この配列の観点から、実行できることが 2 つあります。配列全体の割り当てを解除できます。これにより、含まれているオブジェクトに対する配列の要求が放棄されます。それらが他に所有されていない場合は、割り当てが解除されます。配列自体は保持したいが、そのすべての項目を解放したい場合は、removeAllObjects;を使用します。この場合も、アイテムを所有するものが他にない場合は、アイテムの割り当てが解除されます。

重要な点は、他の誰かそれらを所有している場合、それにはおそらく正当な理由があるということです。

于 2013-01-10T20:19:12.953 に答える