0

ファイルを開くためのダイアログを表示するだけの OS X 用の基本的な動的ライブラリを構築しようとしています。私のコードは次のようになります。

NSOpenPanel * dlg = [NSOpenPanel openPanel];
...//setting title and other properties for dlg

dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_main_queue(), ^
{
    resButton = [dlg runModal];
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
if (resButton == NSFileHandlingPanelOKButton)//resButton is global
{...}

これは基本的に機能しますが、すべてが少しずれています。

- ダイアログがまったく同じ方法で 2 回初期化されることはありません (異なる初期ディレクトリ、レイアウト モードなど)。

-別のディレクトリを選択し、最初のディレクトリをもう一度選択するまで、最初のディレクトリが空として表示されることがあります。

-「右クリック」メニューが表示されません。

- スクロール バウンス バック効果が機能しません (!!!)。すべてが消えるまで、無限に下にスクロールできます。

-列モードでは、プレビューは機能しません (ロード アイコンが永遠に変わります)。 ただし、大きいアイコン モードで表示すると、画像は適切なプレビューになります。

実行されていない更新スレッド全体があるようです。おそらく、lib が呼び出される奇妙なコンテキストにリンクされています: JNA を使用する Java プログラムから。しかし、誰かが「[system startUpdateTask]を呼び出すだけ」など、問題を解決できる小さなトリックを知っていることを願っています:)

助けてくれてありがとう

4

1 に答える 1

1

(コメント返信後:)

試してみてください(シナリオをテストできません)。NSOpenPanel/NSSavePanelは、サンドボックスの導入以来非常にデリケートなクラスであり、慎重に扱う必要があります。

あなたが発見したように、すべてのUI操作はメインスレッドで実行する必要があります。ただし、関数を使用する代わりにdispatch_*、同期を使用してみてくださいperformSelectorOnMainThread

NSOpenPanel * dlg = [NSOpenPanel openPanel];
... //setting title and other properties for dlg

resButton = [dlg performSelectorOnMainThread:@selector(runModal)
                                  withObject:nil
                               waitUntilDone:YES];

if (resButton == NSFileHandlingPanelOKButton) //resButton is global
{...}

それはあなたの問題を解決するかもしれません...

補遺

残念ながら、あなたが正しく指摘しているperformSelectorOnMainThreadように、値は返されません。代わりに次のことができます。

resButtonクラスにインスタンス変数として追加します。

メソッドを追加します。

- (void) myRunModal:(NSOpenPanel *)dlg
{
   resButton = [dlg runModal];
}

コードを次のように変更します。

[self performSelectorOnMainThread:@selector(myRunModal:)
                       withObject:dlg
                    waitUntilDone:YES];

または似たようなもの。

于 2013-10-10T21:08:53.097 に答える