1

自動解放プールを空にしました。警告*** attempt to pop an unknown autorelease poolは、自動解放プールがさまざまな方法で作成および排出されたことを意味します-それは問題ありません。

しかし、それはそのようなプールが排出されていないことを意味しますか?解決策はありますか?

4

1 に答える 1

5

@itaiferberは正しくなく、彼がリンクしているDevBlogの投稿も正しくありません。

NSAutoreleasePoolsはスタックに作成されません。他のすべてのCocoaオブジェクトと同様に、これらはヒープに割り当てられます。

混乱の原因は、ドキュメントに次のように書かれていることだと思います。

各スレッド(メインスレッドを含む)は、NSAutoreleasePoolオブジェクトの独自のスタックを維持します(「スレッド」を参照)。新しいプールが作成されると、それらはスタックの一番上に追加されます。プールの割り当てが解除されると、それらはスタックから削除されます。

ドキュメントで参照されている「スタック」は、呼び出しスタックではなく、スタックデータ構造です。つまり、「自動解放プール1」があり、2番目の自動解放プールを作成してからオブジェクトを自動解放すると、2番目の自動解放プールが空になるとオブジェクトが解放されます。

要約すると、メモリへの影響を理解している限り、ある方法で自動解放プールを作成し、別の方法でそれを排出することは大歓迎です。(これが悪いデザインであるかどうかはまったく別の質問です)

最終的にプールを排出しない場合は、親の自動解放プールが排出されたときにプールが排出されます。

スタックの最上位ではない自動解放プールを解放すると、スタック上のその上のすべての(解放されていない)自動解放プールが、それらのすべてのオブジェクトとともに解放されます。終了時に自動解放プールにリリースを送信しなかった場合(推奨されないこと)、ネストされている自動解放プールの1つが解放されたときに解放されます。

したがって、自動解放プールスタックが次のようになっている場合:

 _____
|  1  |  <--- most recently allocated pool
|-----|
|  2  |
|-----|
|  3  |  <--- least recently allocated pool
 -----

次に、プール3を排出し、プール2と1も自動的に排出されます。これがあなたのコードで起こっていることだと思います。「プール1」を作成していて、「プール3」が排出されると自動的に排出され、プール1を自分で排出しようとしていますが、無効になり、「不明なものをポップしようとしています」自動解放プール」。

この問題は、GUIアプリケーションでプールの自動解放を続けようとしている場合に特に明らかであるためです。このようなアプリケーション(UIKitまたはAppKitベース)では、実行ループはループのすべてのパスで自動解放プールを作成および破棄します。つまり、ループの反復中に作成した自動解放プールは、次にループが発生したときに破棄されます。その周り。

これに関するより具体的な情報については、プールの自動解放に関するメモリ管理プログラミングガイドのセクション全体があります。

于 2010-08-14T21:30:47.923 に答える