0

私は独自のバージョンの NSViewController を実装しようとしています (後方互換性のため)、バインディングで問題が発生しました: バインディングはターゲットを保持するため、ファイルの所有者を介してバインドするたびに円を保持します。

だから私はスーパービューからビューを明示的に削除し、トップレベルのオブジェクトを解放するだけでよいと考えました。これでバインディングが処理されます。これは、コントローラーがビューを保持していないためです。どこかに行って。しかし、何らかの理由で、私のビュー コントローラーはまだ解放されません。問題を示すサンプルアプリを次に示します。

http://dl.dropbox.com/u/34351/BindingsLeak.zip

ビルドして起動し、Cmd-K (「編集」メニューの「ニブの作成」) を押して、空のウィンドウに NIB をロードします。Cmd-K をもう一度押して、最初のビュー コントローラー (TestNibOwner) を解放し、新しいビュー コントローラーをロードします。ただし、古いView Controllerの割り当てが解除されることはありません。

チェックボックスの「値」バインディングを削除すると、問題なく解放されます。

release/retain/autorelease のオーバーライドにブレークポイントを設定すると、_NSBindingInfo が TestNibOwner を保持していることがわかりますが、リークの場合には決して解放されません。

誰でもこれを修正する方法を知っていますか?

4

3 に答える 3

2

class-dump や友人たちと少し調査したところ、Apple には NSAutounbinder と呼ばれるプライベート クラスがあり、NSViewController や NSWindowController などのクラスのこの汚い作業を処理しているようです。それがどのように機能するか、またはそれを複製する方法を実際に伝えることはできません。

したがって、ロードされた nib 内の任意のバインディングに対して保持サイクルが発生するのを防ぐ方法に関するあなたの質問に、私は実際には答えられませんが、おそらく、Apple が不正行為を行っていることを知ることは慰めになるでしょう。:-)

于 2010-01-17T16:40:00.560 に答える
1

同じ問題に対して私が行ったことの 1 つは、ペン先内にプロキシ NSObjectController を作成することです。私の NSViewController のようなクラスには、このプロキシへのポインタがあり、すべてのバインディングはそれを介してバインドされます。ビュー コントローラーをクリーンアップする場合は、オブジェクト コントローラーで [selfProxy setContent:nil] を実行し、ビュー コントローラーを解放します。この場合、NSObjectController プロキシは自動アンバインダーとして機能します。

それはより手動であり、ビューを単独で解放することはできませんが、保持の問題は解決します。

これを行うことをお勧めします:

-(void) releaseTopLevelObjects
{
    // Unbind the object controller's content by setting it to nil.
    [selfProxy setContent:nil];

    NSLog( @"topLevelObjects = %@", topLevelObjects );
    [topLevelObjects release];
    topLevelObjects = nil;
}

nib では、バインディングは次のようなパスを介して行われます。

selfProxy.content.representedObject.fooValue
于 2010-01-17T19:04:17.873 に答える
0

スーパービューからビューを削除すると、別の -release メッセージも送信されますか? ペン先から解凍して作成したものですよね?

于 2010-01-17T13:55:13.603 に答える