1

私はSwingアプリを持っていてJNINSOpenPanel. 一部のコンピューターでは (残念ながら類似点は見つかりませんでした)、アプリが完全にハングします。ほとんどのコンピュータでは正しく動作します。コードが特定の Mac でアプリをハングさせる場合、アプリが実行されるたびにハングします。

NSOpenPanel を開く方法は次のとおりです。

JNF_COCOA_ENTER(env);    
// My helper Obj-c object to make a selector call
OpenFileObject *openFile = [[OpenFileObject alloc] init];    
if ([NSThread isMainThread])
    [openFile showOpenFileDialog];
else
    [JNFRunLoop performOnMainThread:@selector(showOpenFileDialog) on:openFile withObject:nullptr waitUntilDone:TRUE];
// ...Handles results    
JNF_COCOA_EXIT(env);

そしてここにshowOpenFileDialog方法があります:

NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseFiles:canChooseFiles];
[panel setCanChooseDirectories:canChooseFolders];
[panel setAllowsMultipleSelection:allowMultiSelection];
[panel setAllowedFileTypes:fileTypes];
[panel setTitle:dialogTitle];

if ([panel runModal] == NSFileHandlingPanelOKButton)
    urls = [[panel URLs] copy];
else
    urls = nullptr;

ここにハングレポートがあります: https://gist.github.com/4207956

何か案は?

4

3 に答える 3

1

まず、これがあなたの問題と関係があるとは思えませんが、代わりに次のことを行うためnullptrTRUE引数として使用することには注意が必要です。performOnMainThread:...

[JNFRunLoop performOnMainThread:@selector(showOpenFileDialog) on:openFile withObject:nil waitUntilDone:YES];

安全のために。

スタックトレースから、それがすべて1つの大きなスタックであり、ヘルパーオブジェクトメソッド呼び出しに関するコメントを追加するためにそれを分離したと仮定すると、取得されるコードパス[NSThread isMainThread]はNOを返すもののようです。これは、バックグラウンドスレッド上にあることを意味する必要があります(__NSThreadPerformPerformその後、の入札を実行していJNFRunLoopます)。

スタックは、の初期化パスから外れることはなくNSOpenPanel、どういうわけか、最下部のはるか下で、再び実行ループにアクセスしています。私の考えでは、ある種のデッドロックが発生しているようです。

メソッドの実行がメインの実行ループで完了するのJNFRunLoopを別のスレッドで待機していて、の何かが同じ実行ループ内の処理を待機しようとしている場合、デッドロックが発生する可能性があります。showOpenFileDialogopenPanel

JavaとCocoaの統合に慣れていませんが、メイン以外のスレッドでコードの最初のスニペットを実行しないようにする方法はありますか?

または、次を使用してみてください。

[openFile performSelectorOnMainThread:@selector(showOpenFileDialog) withObject:nil waitUntilDone:YES];

非メインスレッドパスで?

于 2012-12-14T05:04:25.907 に答える
0

犯人を見つけました。この問題は、MacOS のアクセシビリティ API を訴える別のアプリが原因でした。モーダル ダイアログが表示されると、メインの Java フレームが必要なネイティブ アクセシビリティ API 呼び出しに応答せず、アプリ全体がハングします。ネイティブのモーダル ダイアログを回避すると、問題が解決します。

たとえば、NSOpenPanel の場合は、に変更[panel runModal]する必要があり[panel beginSheetModalForWindow]ます。これで問題は解決します。

于 2019-04-12T16:45:23.477 に答える