2

NSPanel奇妙な動作に問題があり、この動作を示すサンプル アプリを作成しました。

アプリは Xcode 4 のテンプレートから生成され、単純にパネルを作成し、ボタンの押下に基づいてパネルを開閉します。

ここに画像の説明を入力

私が観察した奇妙な動作:

  1. Lion では、パネルを初めて開いた後、パネルはメイン ウィンドウをたどります。これは正しい動作です。ただし、閉じてから再度開くと、メインウィンドウに追従しなくなります。
  2. Snow Leopard では、パネルを閉じるとメイン ウィンドウも閉じられます。

編集:明確にするために。私が期待する動作は、メイン ウィンドウが移動されたときにパネルがメイン ウィンドウに追従することです。パネルが閉じられ、その後再び開かれた後も、それは真実です。また、Snow Leopard と Lion でパネルとメイン ウィンドウが同じように動作することも期待していました。

コードの重要な部分は次のとおりです。

@implementation MyAppDelegate

- (void)dealloc
{
    [_panel release];
    [super dealloc];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    _panel = [[NSPanel alloc]
             initWithContentRect:NSMakeRect(400, 400, 200, 100)
             styleMask:NSUtilityWindowMask|NSClosableWindowMask|NSTitledWindowMask
             backing:NSBackingStoreBuffered
             defer:YES];
    [_panel setTitle:@"A Panel"];
}

- (IBAction)openPanel:(id)sender
{
    [_panel setParentWindow:[self window]];
    [_panel makeKeyAndOrderFront:sender];
}

- (IBAction)closePanel:(id)sender
{
    [_panel orderOut:sender];
}

@end

注: メソッドに不要なsetParentWindow呼び出しを追加しopenPanelて、パネルが開かれるたびに親ウィンドウがリセットされることをアサートしました。しかし、違いはありませんでした。

誰かが私が間違っていることを説明してもらえますか?

編集:実装ファイルに欠落があることについて混乱があり@synthesize window = _windowますが、メモリリークの動作をテストするために作成した別のプロジェクトサンプルを開いたところ、そこにもありません。私は Xcode 4.4 を使用しているため、バグである可能性がありますが、プロジェクト テンプレートは変更されていないと思います。

4

2 に答える 2

3

親子関係を子からではなく、親から設定することになっています。setParentWindow:ドキュメントによると:

このメソッドは、サブクラスの実装によってオーバーライドされるときに、サブクラスから呼び出す必要があります。それ以外の場合は呼び出さないでください。

代わりに、addChildWindow:ordered:次のように使用します。

- (IBAction)openPanel:(id)sender
{
    [[self window] addChildWindow:_panel ordered:NSWindowAbove];
    //[_panel setParentWindow:[self window]];
    [_panel makeKeyAndOrderFront:sender];
}

Snow Leopardでこれをテストしませんでしたが、Lionで実行したときの動作が修正されました。

Rob Kenigerは、Snow Leopard[[self window] removeChildWindow:_panel]では、パネルを注文する前にも行う必要があると以下に述べています。(これはLionでも良い考えだと思います。)

于 2012-04-29T22:12:23.813 に答える
0

私はあなたの質問について少し混乱しています。あなたのプロジェクトをダウンロードしてチェックアウトしました。まず、どういうわけか、アプリケーションのメイン ウィンドウの @synthesize コマンドがありません。テンプレートを使用したとおっしゃいましたが、どういうわけか欠落しています。AppDelegate ヘッダー ファイルにはウィンドウの @property があるため、その実装ファイルに @synthesize コマンドが必要です。プロジェクトでその行をどのように失ったのかわかりませんが、 @implementation 行の直後にこれを追加してください...

@synthesize window = _window;

第二に、なぜ次のように述べているのですか?

Lion では、パネルを初めて開いた後、パネルはメイン ウィンドウに追従しますが、これは正しい動作です。

あなたの言っていることは意味がありません。パネルを作成するときは、「initWithContentRect:NSMakeRect(400, 400, 200, 100)」を使用します。サイズが (200, 100) の位置 (400, 400) に作成することに注意してください。したがって、最初に開くと、画面の場所 (400、400) で開きます。メインウィンドウの位置とは関係ありません。

とにかく、 @synthesize 部分を追加した後、エラーなしでアプリケーションをコンパイルして実行できました。私にとっては、10.7で期待どおりに機能しています。

于 2012-04-29T21:58:20.140 に答える