私見、どちらが「正しい」かは好みの問題です。を使用しないことを主張するレスポンダーに同意しませんが、圧倒的にやむを得ない理由がない限りautorelease
、使用することを好みます。autorelease
私の理由をリストします。あなたのプログラミング スタイルに適しているかどうかを判断してください。
Chuck が指摘したように、自動解放プールを使用すると何らかのオーバーヘッドが発生するという半都市伝説があります。これは真実からかけ離れたものではなく、Shark.app を使用してコードからパフォーマンスの最後のビットを絞り出すために数え切れないほどの時間を費やした結果です。これを最適化しようとすることは、「時期尚早の最適化」の領域に深く入り込みます。Shark.app が、これが問題である可能性があるという確固たるデータを提供する場合に限ります。
他の人が指摘したように、自動解放されたオブジェクトは「後で解放されます」。これは、その「後の時点」が転がるまで、それらが残り、メモリを占有することを意味します。「ほとんど」の場合、これは、次のイベント (タイマー、ユーザーが何かをクリックするなど) まで実行ループがスリープする前のイベント処理パスの最後にあります。
ただし、場合によっては、これらの一時オブジェクトを後でではなくすぐに削除する必要があります。たとえば、巨大な数メガバイトのファイル、またはデータベースからの数万行を処理する必要があります。NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
これが発生した場合、適切に選択されたポイントに a を配置し、続い[pool release];
て下部に aを配置する必要があります。これはほとんどの場合、ある種の「ループ バッチ処理」で発生するため、通常は重要なループの最初と最後で発生します。繰り返しますが、これは勘に基づくのではなく、証拠に基づく必要があります。Instrument.app の ObjectAlloc は、これらの問題点を見つけるために使用するものです。
ただし、私が を好む主な理由は、リークのないプログラムを作成する方がautorelease
はるかに簡単だからです。要するに、ルートを選択した場合、最終的に が に送信されることを、あらゆる状況下で保証する必要があります。これは簡単そうに見えて、実際にやってみると意外と難しいものです。たとえば、あなたの例を見てください:release
release
release
obj
// array is an instance of NSMutableArray
MyClass *obj = [[MyClass alloc] init];
[array addObject:obj];
// Assume a few more lines of work....
[obj release];
なんらかの理由で、何かが、どこかでarray
、おそらく結果を処理するために何らかのメソッドを使用した結果として、可変であるという仮定に微妙に違反し、処理された結果を含む返された配列が として作成されたと想像してくださいNSArray
。addObject:
その immutableに送信すると、例外がスローされ、そのメッセージNSArray
は送信されません。または、 d と必要なへの呼び出しの間のどこかで何か問題が発生した可能性があります。たとえば、何らかの条件を確認してすぐに誤って、 への呼び出しが後で行われる必要があることを忘れてしまった場合などです。obj
release
obj
alloc
release
return()
release
オブジェクトをリークしました。そして、おそらく、あなたが漏らしている場所と理由を突き止めようとして、数日間サインアップしたことでしょう。経験上、あなたは何時間もかけて上記のコードを見て、非常に明確obj
にrelease
. それから数日後、あなたは問題の原因を悟り、宗教的なひらめきとしか言いようのないものを体験するでしょう。
ケースを考えてみましょうautorelease
:
// array is an instance of NSMutableArray
MyClass *obj = [[[MyClass alloc] init] autorelease];
[array addObject:obj];
// Assume a few more lines of work....
obj
今では、非常に珍しい、または例外的なコーナーケースであっても、誤ってリークすることは事実上不可能であるため、何が起こっても問題ではありません.