19

私はこれを読んだ:

アプリケーションでセカンダリスレッドを作成する場合は、独自の自動解放プールを提供する必要があります。自動解放プールとそれに含まれるオブジェクトについては、

iOS5Developerクックブックにあります。

ARCでコンパイルしています。私は多くのバックグラウンドスレッドを作成してきましたが、うまくやっているようです。私のバックグラウンドスレッドはどれも長時間実行されていません。これらのオブジェクトはすべて、たとえばメインスレッドの自動解放プールによって解放されるのでしょうか。または何?

これは私がバックグラウンドスレッドと呼ぶために行うことです:

+(void)doBackground:(void (^)())block
{
    //DISPATCH_QUEUE_PRIORITY_HIGH
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{
    dispatch_async(dispatch_get_global_queue(-2,0), ^{
        block();
    });
}

これをに変更する必要があります

+(void)doBackground:(void (^)())block
{
    //DISPATCH_QUEUE_PRIORITY_HIGH
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{
    dispatch_async(dispatch_get_global_queue(-2,0), ^{
        @autoreleasepool{
        block();
        }
    });
}
4

2 に答える 2

35

新しいスレッドの自動解放プールを作成しない場合は、少なくともプログラマーのエラーと考えてください。それがプログラムにとって致命的かどうかは、プログラムの実装によって定義されます。古典的な問題は、リークされたオブジェクトであり、結果としてdealloc実行されないオブジェクトです (致命的となる可能性があります)。

ARC の下で自動解放プールを作成する最新の方法は次のとおりです。

void MONThreadsEntry() { // << entry is e.g. a function or method
  @autoreleasepool {
    ...do your work here...
  }
}

より詳細には、自動解放プールはスレッド ローカル スタックとして動作します。プッシュおよびポップできますが、そのスレッド上の何かが自動解放される前に、常に 1 つのスタックが配置されている必要があります。自動解放メッセージは、あるスレッドから別のスレッドに転送されません。

「スレッドを作成する」という考えが NSOperationQueue の使用などの高レベルの非同期メカニズムを使用している場合、または基礎となる実装がセカンダリ スレッドと独自の自動解放プールを作成している場合、問題 (コンソールやリークなど) が表示されない場合があります。 .

とにかく、いつ自動解放プールを作成するかを推測するのではなく、どこに作成する必要があるか、いつ作成する必要があるかを学んでください。それはすべて明確に定義されています。当て推量の必要はなく、それらを作成することを恐れる必要はありません。

同様に、低レベルの抽象化を使用している場合は、スレッドの自動解放プールを作成する必要はなく、そのスレッドでオブジェクトを自動解放する必要はありません。たとえば、pthreads と純粋な C 実装では、自動解放プールを気にする必要はありません (使用する API が適切であると想定しない限り)。

Cocoa アプリのメイン スレッドでさえ、自動解放プールが必要です。これは、プロジェクト テンプレートに存在するため、通常は作成するものではありません。

更新 -- ディスパッチ キュー

更新された質問への回答:はい、ディスパッチ キューで実行されるプログラムの自動解放プールを引き続き作成する必要があります。ディスパッチ キューではスレッドを作成していないため、元の質問とはまったく異なる質問です。理由: ディスパッチ キュー自動解放プールを管理しますが、それらが空になる時間/ポイントに関しては保証されません。つまり、オブジェクトは (ある時点で) 解放されますが、そうする必要があります。また、このコンテキストで自動解放プールを作成します。これは、実装が (理論的には) 実行される 10,000 ブロックごと、またはほぼ毎日プールを空にする可能性があるためです。したがって、このコンテキストでは、最終的に大量のメモリを消費する場合や、オブジェクトが特定の方法で破棄されることをプログラムが予期している場合などのシナリオでのみ致命的です。自動解放プールのためにこれらのイメージの寿命が予期せず延長された場合、大量のメモリを消費することになります。もう 1 つの例は共有リソースまたはグローバル オブジェクトです。「ブロック ローカル」オブジェクトは予想よりもずっと長く存続する可能性があるため、通知に応答したり、競合状態を導入したりする可能性があります。

于 2012-09-25T04:17:26.253 に答える
4

新しいスレッドの自動解放プールが自動的に作成されるようになりました。これがいつ変更されたのか、ドキュメントが反対の理由を述べているのかはわかりませんが、それだけです。

于 2012-09-25T01:44:46.033 に答える