2011-01-07 5 views
1

NSAutoReleasePoolの仕組みを理解するのが難しいです。NSAutoreleasePool EXC_BAD_ACCESSとObjective-Cでのメモリ管理について

1)NSAutoReleasePoolは、各割り当てを個別に追跡しますか、それとも変数に依存して動作しますか?換言すれば、このリークメモリを行い、または放出の両方?:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
NSArray* myObj = [NSObject alloc]; 
myObj = [NSObject alloc]; 
[pool release]; 

2)なぜ次のコード作業:

NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; 

NSArray* myObj = [NSObject alloc]; 

for(int i = 0; i < 100; i++) { 
    [myObj release]; 
    myObj = [NSObject alloc]; 
} 

[pool1 release]; 

が、以下は、[pool1 release]にEXC_BAD_ACCESSを与える:

NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; 

NSArray* myObj = [NSObject alloc]; 

NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; 

for(int i = 0; i < 100; i++) { 
    [myObj release]; 
    myObj = [NSObject alloc]; 
} 

[pool2 release]; 
[pool1 release]; 

3)上のコード(2つのプールを持つもの)?

+1

次回は、を使用しないでください。パネル内で「」をクリックするか、{}記号をクリックしてください。これはここでのやり方です:D – vodkhang

+0

知らなかった。ありがとう – Caner

+2

あなたはautoreleaseプールが_autoreleased_オブジェクトをリリースし、任意のオブジェクトをリリースする責任があることに気づいていません。あなたのテストオブジェクトを初期化していないだけでなく、オートレリースしていないので、オートリリースプールはそれらに触れません。 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html%23//apple_ref/doc/uid/20000043-BEHDEDDBおよびhttp://developer.appleを参照してください。 .com/library/mac /#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html%23 // apple_ref/doc/uid/20000047-CJBFBEDI –

答えて

5

自動解放プールは、自動解放するオブジェクトに対してのみ機能します。コード内のオブジェクトはオートレリースされていないため、作成したプールの影響を受けません。

したがって、答えは以下のとおりです。

  1. (どちらか放出されないか、自動解放され、どちらもいるので)それはそれはない
  2. 両方のオブジェクトをリーク。割り当てられた最後のオブジェクトがリークします
  3. The documentation says that you can nest them[NSObject alloc]があると仮定すると、実際には[[[NSObject alloc] init] autorelease]を意味します。myObjを最初にリリースすると、pool2の外に宣言されたオブジェクトになるため、2番目のコードサンプルは失敗します。これは、あなたがreleasepool1のとき、既にリリースされているオブジェクトを解放しようとすることを意味します。それを有効にする方法は、保持または割り当てよりも多くの時間、オブジェクトを解放(または自動解放)しないことです。
2

NSAutoreleasePoolは割り当ての追跡を行いません。 autoreleaseというメッセージをオブジェクトに送信すると、そのスレッド上で自動解放プールが検索されます(実行ループの各トリップの先頭に自動的に作成され、一番下に割り当て解除されます)。ほとんどの場合、それらを手動で作成する)。見つかった場合は、自動解放プールが維持するオブジェクトのリストに追加されます。

自動解放プールの割り当てが解除されると、リスト内の各項目にreleaseメッセージが送信されます。アイテムがリストに複数回追加された場合、アイテムは複数回リリースされます。

あなたのコードがEXC_BAD_ACCESSを取得する理由については、わかりません。あなたのNSObjectsにinitを呼び出さなかったという事実、またはあなたがまだ私たちに示していないコードと関連しているかもしれません。

2

いくつかのこと:

:オブジェクトを作成するときは、必ずinitメソッドを使用しています。 ([[NSObject alloc] init])

:オブジェクトは、自動リリース時にオートレリープールに追加されます。この例のオブジェクトは単に解放されているので、autoreleaseプールはまったく使用されません。これはすべての自動解放プールを削除することで確認できます。コードはまだ正常に機能します。

:最初の例ではメモリがリークします。 2つのオブジェクトを割り当てて、どちらも解放しません。あなたがそれらを自動放棄するのであれば、おそらくあなたが探している行動を得ているだろうし、リークはないでしょう。

:例2は、オブジェクトを解放するだけであるため、割り当てを行っているため動作します。オートリリースプールを使用しているものはありません。あなたはこれを見るためにオートリリースコードを削除することができます。

:例3の動作を再現することができませんでした。おそらくコード内で何か他のことが起こっている可能性があります。