3

NSOpenPanel を閉じる方法を理解するのに苦労しています。自動的に閉じますが、必要以上に時間がかかります。

これが私のコードです:

- (IBAction)startProcess:(id)sender
{

   NSString *path = [Document openVideoFile]; // open file

   // some other method calls here
}

// NSOpenPanel for file picking
+(NSString*) openVideoFile
{
   NSOpenPanel *openDialog = [NSOpenPanel openPanel];

   //set array of the file types

   NSArray *fileTypesArray = [[NSArray alloc] arrayWithObjects:@"mp4", nil];

   [openDialog setCanChooseFiles:YES];
   [openDialog setAllowedFileTypes:fileTypesArray];
   [openDialog setAllowsMultipleSelection:FALSE];

   if ([openDialog runModal] == NSFileHandlingPanelOKButton)
   {      
      NSArray *files = [openDialog URLs];

      return [[files objectAtIndex:0] path];   
   }
   else
   {
      return @"cancelled";
   }
   return nil; // shouldn't be reached
}

興味深いことに、ユーザーが「キャンセル」をクリックすると、パネルはすぐに閉じますが、ユーザーがリストからファイルを選択すると、プログラムが startProcess メソッドの最後に到達するまでパネルは開いたままになります。

ユーザーがファイルを選択した後に [OK] ボタンをクリックした後、すぐにパネルを閉じる方法を誰かが知っていれば、助けていただければ幸いです。

ありがとうございました!

4

3 に答える 3

4

私の推測では、システムは実際には、開いているパネルを削除するアニメーションを実行ループの後半まで開始しないと思いstartProcess:ます。したがって、「<code>ここで他のメソッドを呼び出す」の実行に時間がかかる場合、アニメーションが始まるまでに長い時間がかかります。

理想的な解決策は、バックグラウンド キューで遅い「他のメソッド呼び出し」を実行することです。これは、メイン スレッドをブロックしないようにする必要があるためです。しかし、そのためには、現在スレッドセーフになっていないさまざまなことをスレッドセーフにする必要があり、それは難しいかもしれません。

別のアプローチは、実行ループの後半まで実行を延期することです。

- (IBAction)startProcess:(id)sender {
    NSString *path = [Document openVideoFile]; // open file
    dispatch_async(dispatch_get_main_queue(), ^{
       // some other method calls here
    });
}

または、それよりも少し長く延期する必要があるかもしれません:

- (IBAction)startProcess:(id)sender {
    NSString *path = [Document openVideoFile]; // open file
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 100), dispatch_get_main_queue(), ^(void){
        // some other method calls here
    });
}
于 2012-11-13T05:20:25.930 に答える
1

バックグラウンド スレッドで遅い作業を行うというアドバイスは適切です。

ただし、パネルをすぐに閉じるには、[openDialog close]から戻る前に呼び出します-openVideoFile

于 2012-11-13T05:37:24.157 に答える