2

Advanced Memory Management Programming Guideは、@autoreleasepool について次のように述べています。

ローカル自動解放プール ブロックを使用してピーク メモリ フットプリントを削減する

多くのプログラムは、自動解放される一時オブジェクトを作成します。これらのオブジェクトは、ブロックの最後までプログラムのメモリ フットプリントに追加されます。多くの場合、現在のイベント ループの反復が終了するまで一時オブジェクトを蓄積できるようにしても、過度のオーバーヘッドは発生しません。ただし、場合によっては、大量の一時オブジェクトを作成してメモリ フットプリントを大幅に増やし、より迅速に破棄する必要がある場合があります。後者の場合、独自の autorelease プール ブロックを作成できます。ブロックの最後に、一時オブジェクトが解放されます。これにより、通常は割り当てが解除され、プログラムのメモリ フットプリントが削減されます。

次の例は、for ループでローカル自動解放プール ブロックを使用する方法を示しています。

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {

    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url
                                         encoding:NSUTF8StringEncoding error:&error];
        /* Process the string, creating and autoreleasing more objects. */
    }
}

このコードは、autoreleasepool を使用せずに記述して効率的に管理することもできますか?

を作成し、処理後にproperty of fileContents設定するようなものです。nil

self.filecontents = nil;
4

3 に答える 3

5

問題はstringWithContentsOfURL、自動解放されたオブジェクトを返すことができることです。initWithContentsOfURLただし、代わりに次を使用できます 。

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
    NSError *error;
    NSString *fileContents = [[NSString alloc] initWithContentsOfURL:url
                                     encoding:NSUTF8StringEncoding error:&error];
    /* Process the string ... */
    fileContents = nil;
}

init...メソッドは、自動解放されたオブジェクトではなく、(+1) 保持されたオブジェクトを返すため fileContents = nil、オブジェクトを解放して破棄します (他に強い参照がない場合)。

もちろん、これは「文字列処理コード」が他の自動解放オブジェクトを生成しない場合にのみ役立ちます。(またerror、設定されている場合は、自動解放されたオブジェクトになります。)

(実際には、自動解放されたオブジェクトを返すことは「保証」されていませんstringWithContentsOfURL。特にリリース モードでは、ARC コンパイラは多くの不要な保持/自動解放/解放操作を削除します。)

ローカル自動解放プールの確立が高価な操作であるかどうかはわかりません (そうではないと思います)。ループ内で多くのオブジェクトを処理し、自動解放されたオブジェクトが作成されたかどうかが正確にわからない場合は、ローカルの自動解放プールを使用して「気にしない」ことが賢明な場合があります。「Instruments」を使用してプロファイリングすると、さらに洞察が得られる可能性があります。

詳細については、Clang ARC ドキュメントの「保持される戻り値」と「保持されない戻り値」を参照してください。

于 2013-08-11T08:39:32.693 に答える
1

強力なプロパティに割り当ててからそれを nil-out し、強力なローカル変数に割り当ててスコープ外にすることに違いはありません。fileContents根本的な問題は、少なくともforループがすべての URL の反復を完了するまで、割り当てられたオブジェクトが自動解放プールに配置されることです。ループ本体を@autoreleasepoolブロック内fileContentsに配置すると、ループの反復ごとに自動解放されます。

于 2013-08-11T08:40:13.870 に答える
0

表面上はそのように見えますが、cocoa メソッドを呼び出すと、舞台裏で自動解放されたオブジェクトが作成される可能性があります。自動解放プールを使用せずに別のスレッドで同じ種類の操作を実行するとわかるように。

長時間ループを実行している場合は、別のプールを追加することをお勧めします。

より人気のある次のようなモデルもあります。

NSAutoreleasePool * pool = [NSAutoreleasePool new];
for (int i =0;i>3009;i++){
    //do stuff;
    if(!(i%100))
    {
        [pool drain],pool = [NSAutoreleasePool new];}
}
[pool drain];
于 2013-08-11T17:31:14.230 に答える