19

ARCの下ARCでは、ループ用の@autoreleasepoolを作成することをお勧めしますか?

NSData* bigData = ... 
while(some condition) { 
    NSData* smallData = [bigData subdataWithRange:...]; 
    //process smallData 
} 

...のは、私は自動解放のNSDataオブジェクトの束を返すループを持っているとしましょう、私はまだwhile条件の周り@autoreleasepoolをラップする必要がありますか?

NSData* bigData = ... 
@autoreleasepool { 
    while(some condition) { 
     NSData* smallData = [bigData subdataWithRange:...]; 
     //process smallData 
    } 
} 

私が求めている理由は、私がinitWith...方法とは対照的に、dataWith...メソッドを呼び出し、私のNSDataオブジェクトの屋根を通過する機器の生活割り当て数を参照してくださいです。 initWith...を使用すると、生きている割り当て数はずっと少なくなります。

可能な限りinitWith...メソッドを使用する方がよいですか?

答えて

13

はい、タイトなループで便利なメソッドを使用する場合は、自動解放プールを使用する必要があります。すべての古いメモリ管理ルールはARCの下でも適用されますが、コンパイラはRRを注入するだけです。すばらしいマイクアッシュの素晴らしいポストをチェックアウトしてください! ARCの下

Link

+0

すばらしいリンクをありがとう! –

+10

@ Chuckの答えによると、@autoreleasepoolはループを実行する必要があります。イディオムは、@autoreleasepool {while(x){...}}ではなく 'while(x)@autoreleasepool {...}'です。 – Quuxplusone

+0

これはあまり単純化されず、正しくありません。 ARCは、+0オブジェクトを返すメソッドの自動解放プールの使用を最適化することがよくあります(これは、ほとんどの場合、 'autorelease'を使用しています)。 –

7

、私はまだwhile条件の周り@autoreleasepoolをラップする必要がありますか?

はい。 Autorelease Poolsはまだ存在し、前と同じように成長してポップします。コンパイラは、TUで表示されるメソッドとデフォルトの命名規則に基づいて、ARCが有効な場合(Loganをエコーする)、必要な保持および解放操作を追加して結合します。

ARCでの実行は手動参照カウントとほぼ同じです。自動解放プールスタックはまだ存在します。 1つの相違点は、コンパイラが参照カウント操作を書いた方法とは少し違った順序で(不正な方法ではなく)並べ替えることであり、不要な保持サイクルを省略することができる点です。

可能であれば、initWith ...メソッドを使用する方がよいでしょうか?

WRTは、自動リリースされた対応製品と比較してヒープの成長を最小限に抑えます。それはいつもそうだった。これは特にメモリが限られているiOSデバイスでは重要です。

例外は、オブジェクトが割り当てを回避できる場合です。例:この場合

NSString * copy = [NSString stringWithString:arg]; 

copy[[arg retain] autorelease]であってもよいです。この場合、copyは依然として自動リリースされていますが、このような最適化が存在するかどうかをテストするためには、通常は長引くべきではありません。注:ここでもcopy = [arg copy] ... [arg release]を使用する方が良いです。

もう1つの特典は、オブジェクトがオートレリースされていない場合に、オートレスレーティングプールが最終的にポップされるのではなく、コールサイトに近い場合にリフカウントの不均衡が早くキャッ​​チされることです。

大規模な自動解放プールでのパフォーマンスは、実際にはほとんどの人が想定するよりもはるかに悪いです。それらに大きく依存しないようにすることができます(例:alloc + init ...+ release)、プログラムを著しく高速化できます。明示的に自動解放プールを作成することは安価で、この問題を最小限に抑えるのに役立ちます。割り当てが大きい場合や多い場合は、できるだけautoreleaseを使用しないでください。また、明示的な自動解放プールでこれらのセクションをラップしてください。

13

あなたの問題は、自動解放プールがの内側にあると思います。ループです。 autoreleaseブロック内のループではなく、ループを終了すると、ループが終了するまで蓄積されたオブジェクトは解放されません。

+0

私は '@ autoreleasepool'をループ内に置くことを考えていませんでした...チップのおかげで。 –