NSAutoreleasePool クラスリファレンス 翻訳元
このページの最終更新:2010-02-17
ADCの最終更新:2009-01-02
ADCの最終更新:2009-01-02
継承するクラス | NSObject |
準拠しているプロトコル | NSObject (NSObject) |
フレームワーク | /System/Library/Frameworks/Foundation.framework |
使用可能な環境 | Mac OS X v10.0 |
コンパニオンガイド | Cocoaメモリ管理プログラミングガイド |
宣言ファイル | NSAutoreleasePool.h |
サンプルコード | CocoaSpeechSynthesisExample? OpenCL NBody Simulation Example? SpellingChecker CarbonCocoa Bundled? SpellingChecker-CarbonCocoa? SpellingChecker-CocoaCarbon? |
概観(Overview)
NSAutoreleasePoolクラスはCocoaのリファレンスカウンタ方式のメモリ管理をサポートするのに使われます。自動解放プールはオブジェクトをストアし、プール自身がドレインされた時にそのオブジェクトのreleaseメソッドを呼び出します。
(ガーベジコレクション環境と対照的な)リファレンスカウンタ環境では、NSAutoreleasePoolオブジェクトはautoreleaseメッセージを受信したオブジェクトを収容し、ドレインされた時にそれらのオブジェクトにそれぞれreleaseメッセージを送ります。このように、releaseメッセージの代わりにautoreleaseメッセージを送ることで、オブジェクトの寿命を最低でもプールがドレインされるまで(その後保持されればもっと)延ばすことができます。オブジェクトは同じプールに何度か入れることができます。その場合、そのオブジェクトはプールに入れた回数だけreleaseメッセージを受け取ることになります。
リファレンスカウンタ環境では、Cocoaフレームワークは常に自動解放プールが利用可能であることを想定しています。もしプールが利用可能でなければ、autoreleaseメッセージを受け取ったオブジェクトは解放されず、メモリリークとなります。このようなとき、プログラムはたいてい適切な警告をログに出力するでしょう。
Application Kitフレームワークはメインスレッド上ではイベントループの最初に自動解放プールを生成し、最後にプールをドレインします。そのため、イベント中に出力された自動解放されるオブジェクトは全て解放されます。したがって、Application Kitを使っているなら、大抵の場合は独自のプールを作る必要はありません。ただし、アプリケーションが自動解放される一時的なオブジェクトをイベントループ中に大量に生成する場合、メモリ使用量のピークを下げる為に「局所的な」自動解放プールを作った方が良いかもしれません。
NSAutoreleaseオブジェクトは通常のalloc、initメソッドで生成し、drainメソッド(またはreleaseメソッド。違いを理解するには、「ガーベジコレクション(Garbage Collection)」を参照してください)で後始末をします。自動解放プールを保持すること(それと自動解放すること。retainメソッドとautoreleaseメソッドを参照してください)はできません。よって、プールをドレインすることは、結局はメモリの解放と同じ働きをします。自動解放プールは常に生成したのと同じ文脈(関数やメソッド、ループの内部)でドレインするべきです。詳細についてはlink_anchor plugin error : idが指定されていないか、存在しないページを指定しています。を参照してください。
それぞれのスレッド(メインスレッドを含む)は自信のNSAutoreleasePoolオブジェクトのスタックを維持します(「スレッド(Threads)」を参照してください)。新しいプールが作られると、そのプールはスタックトップに積まれます。プールが開放されると、そのプールはスタックから取り除かれます。自動解放されるオブジェクトはその時点でのスレッドの一番上の自動解放プールに収容されます。スレッドが終了すると、関連のある自動解放プールは全て自動的にドレインされます。
(ガーベジコレクション環境と対照的な)リファレンスカウンタ環境では、NSAutoreleasePoolオブジェクトはautoreleaseメッセージを受信したオブジェクトを収容し、ドレインされた時にそれらのオブジェクトにそれぞれreleaseメッセージを送ります。このように、releaseメッセージの代わりにautoreleaseメッセージを送ることで、オブジェクトの寿命を最低でもプールがドレインされるまで(その後保持されればもっと)延ばすことができます。オブジェクトは同じプールに何度か入れることができます。その場合、そのオブジェクトはプールに入れた回数だけreleaseメッセージを受け取ることになります。
リファレンスカウンタ環境では、Cocoaフレームワークは常に自動解放プールが利用可能であることを想定しています。もしプールが利用可能でなければ、autoreleaseメッセージを受け取ったオブジェクトは解放されず、メモリリークとなります。このようなとき、プログラムはたいてい適切な警告をログに出力するでしょう。
Application Kitフレームワークはメインスレッド上ではイベントループの最初に自動解放プールを生成し、最後にプールをドレインします。そのため、イベント中に出力された自動解放されるオブジェクトは全て解放されます。したがって、Application Kitを使っているなら、大抵の場合は独自のプールを作る必要はありません。ただし、アプリケーションが自動解放される一時的なオブジェクトをイベントループ中に大量に生成する場合、メモリ使用量のピークを下げる為に「局所的な」自動解放プールを作った方が良いかもしれません。
NSAutoreleaseオブジェクトは通常のalloc、initメソッドで生成し、drainメソッド(またはreleaseメソッド。違いを理解するには、「ガーベジコレクション(Garbage Collection)」を参照してください)で後始末をします。自動解放プールを保持すること(それと自動解放すること。retainメソッドとautoreleaseメソッドを参照してください)はできません。よって、プールをドレインすることは、結局はメモリの解放と同じ働きをします。自動解放プールは常に生成したのと同じ文脈(関数やメソッド、ループの内部)でドレインするべきです。詳細についてはlink_anchor plugin error : idが指定されていないか、存在しないページを指定しています。を参照してください。
それぞれのスレッド(メインスレッドを含む)は自信のNSAutoreleasePoolオブジェクトのスタックを維持します(「スレッド(Threads)」を参照してください)。新しいプールが作られると、そのプールはスタックトップに積まれます。プールが開放されると、そのプールはスタックから取り除かれます。自動解放されるオブジェクトはその時点でのスレッドの一番上の自動解放プールに収容されます。スレッドが終了すると、関連のある自動解放プールは全て自動的にドレインされます。
スレッド(Threads)
Application Kitのメインスレッド以外でCocoaフレームワークを使用している場合、例えばFoundationのみのアプリケーションやメインスレッドから分離したスレッドの場合には、独自の自動解放プールを生成する必要があります。
アプリケーションやスレッドの寿命があまりに長く、多くの自動解放されるオブジェクトを出力する可能性がある場合、(Application Kitがメインスレッド上で行うように)定期的に自動解放プールを生成、ドレインするべきです。そうしなければ、自動解放されるオブジェクトが累積し、メモリ使用量が上昇します。ただし、分離したスレッドがCocoaフレームワークを使用しないのであれば、自動解放プールを生成する必要はありません。
アプリケーションやスレッドの寿命があまりに長く、多くの自動解放されるオブジェクトを出力する可能性がある場合、(Application Kitがメインスレッド上で行うように)定期的に自動解放プールを生成、ドレインするべきです。そうしなければ、自動解放されるオブジェクトが累積し、メモリ使用量が上昇します。ただし、分離したスレッドがCocoaフレームワークを使用しないのであれば、自動解放プールを生成する必要はありません。
注:もしNSThreadオブジェクトではなく、POSIXスレッドAPIを使って第2のスレッドを生成する場合には、Cocoaがマルチスレッディングモードでない限り、NSAutoreleasePoolクラスを含むCocoaフレームワークを使うことはできません。Cocoaフレームワークは最初のNSThreadオブジェクトが分離した後のみマルチスレッディングモードになります。第2のPOSIXスレッドでCocoaフレームワークを使用する為には、そのアプリケーションでは最低一つのNSThreadオブジェクトが分離していなければなりません。そのスレッドはすぐに終了しても構いません。Cocoaフレームワークがマルチスレッディングモードであるかは、NSThreadクラスのlink_anchor plugin error : idが指定されていないか、存在しないページを指定しています。メソッドで調べることができます。 |
ガーベジコレクション(Garbage Collection)
ガーベジコレクションが有効な環境では、自動解放プールは必要ありません。しかし、ガーベジコレクション環境でもリファレンスカウンタ環境でも動くフレームワークを開発することになるかもしれません。このような時には、自動解放プールをガーベジコレクションが発動するきっかけとして使うことができます。ガーベジコレクション環境下では、drainメッセージをプールに送ると、プールは必要であればガーベジコレクションを開始させます。ですが、releaseメソッドではそのようにはなりません。リファレンスカウンタ環境下では、drainメソッドはreleaseメソッドと同じ効果があります。したがって、通常はreleaseメソッドの代わりにdrainメソッドを使用するべきです。