3

私はMacRubyとCocoaを備えた完全なn00bなので、答えるときはそのことを覚えておいてください。多くの詳細と説明が必要です。:)

2つのウィンドウを含む単純なプロジェクトをセットアップしました。どちらもInterfaceBuilderで構築されています。最初のウィンドウは、テーブルビューを使用したアカウントの単純なリストです。表の下に「+」ボタンがあります。+ボタンをクリックすると、「新しいアカウントの追加」ウィンドウが表示されます。

また、これらのウィンドウのデリゲートとして設定されAccountsController < NSWindowControllerたクラスと、適切なボタンクリックメソッドが配線されたクラス、および必要なウィンドウを参照するためのアウトレットがあります。AddNewAccountController < NSWindowController

[アカウント]ウィンドウの[+]ボタンをクリックすると、次のコードが実行されます。

    @add_account.center
    @add_account.display
    @add_account.makeKeyAndOrderFront(nil)
    @add_account.orderFrontRegardless

これは、最初に[+]ボタンをクリックしたときにうまく機能します。すべてが表示され、データを入力してモデルにバインドすることができます。ただし、新しいアカウントの追加フォームを閉じると、状況が悪化し始めます。

[新しいアカウントの追加]ウィンドウを閉じるときに解放するように設定した場合、2回目に[+]ボタンをクリックすると、ウィンドウはポップアップ表示されますが、フリーズします。ボタンをクリックしたり、データを入力したり、フォームを閉じたりすることはできません。これは、フォームのコードがリリースされたためだと思います。そのため、フォームを処理するメッセージループはありません...しかし、これについては完全にはわかりません。

[新しいアカウントの追加]ウィンドウを閉じたときに解放しないように設定した場合、2回目に[+]ボタンをクリックすると、ウィンドウは正常に表示されて使用できますが、以前に入力したすべてのデータが残っています...以前のAccountクラスインスタンスにまだバインドされています。

私は何が間違っているのですか?[アカウント]フォームの[+]ボタンをクリックしたときに、[新しいアカウントの追加]フォームの新しいインスタンスを作成し、新しいアカウントモデルを作成し、そのモデルをフォームにバインドしてフォームを表示する正しい方法は何ですか?

...これはすべてOSX10.6.6、64ビット、XCode3.2.4で実行されています

4

1 に答える 1

1

問題は、毎回ウィンドウを作成しないことです。Release on close は少し厄介なオプションであり、通常、ウィンドウが閉じるときにウィンドウ コントローラーも解放されることがわかっている場合にのみ使用されます。(注: 私は MacRuby を使ったことがないので、Obj-C が正しいことを知っているので、コードを提供します。変換できることを願っています。MacRuby では GC がオンになっていると仮定します)。

現在、これを行うには 2 つの方法があります。NIB/クラスがどのように設定されているかは完全にはわかりません.2つの方法のいずれかである可能性があります.

--

これを解決する最初の方法は、フォーム要素を参照するために使用するアウトレットを使用して、ウィンドウを再度表示するときにそれらを空白にすることです (例: [myTextField setStringValue:@""])。cocoa バインディングを使用している場合は少し複雑ですが、基本的には、バインドされたオブジェクトが空白になっていることを確認する必要があります。ただし、Cocoa を初めて使用する場合は、バインディングを使用しないことをお勧めします。

--

2 番目の方法は、AddNewAccountController クラスを NSWindowController のサブクラスにすることです。+ ボタンを押すと、新しいインスタンスを作成して表示します (ivar に保存することを忘れないでください)。それを行う最良の方法は次のとおりです。

if (!addAccountController) {
    addAccountController = [[AddNewAccountController alloc] initWithWindowNibName:@"AddNewAccountController"];
    [[addAccountController window] setDelegate:self];
}
[addAccountController showWindow:self];

これにより、ウィンドウが既に表示されている場合に新しいインスタンスが作成されるのを防ぎます。次に、デリゲートを実装する必要があります。

- (void)windowWillClose:(NSNotification *)notification {
    //If you don't create the account in the AddNewAccountController then do it here
    addAccountController = nil;
}

明らかに、ウィンドウを「AddNewAccountController」と呼ばれる別の NIB に移動する必要があります。この NIB で、ファイルの所有者のクラスを AddNewAccountController に設定してから、ファイルの所有者のウィンドウ アウトレットをウィンドウに接続するようにしてください。

これがすべて設定されると、毎回新しいコントローラー/ウィンドウが表示されます。また、ペン先とコントローラーをより集中的なユニットに分割できるという利点もあります。

--

最後に一つだけ。ウィンドウでこのようなことを行うのは問題ありませんが、アカウントの追加ウィンドウが他のウィンドウの後ろに隠れてしまう可能性を防ぐため、シートを介してこれを行うことを最終的に検討することをお勧めします。

于 2011-01-30T15:24:45.750 に答える