2012-01-11 12 views
2

NSWindow + NSViewをプログラムで作成するCocoaベースのコマンドラインアプリケーションがあります。 nextEventMatchingMaskループを使用して、イベント・ループとディスパッチ・イベントを手動でポンピングします。このループは、入力をポーリングするために、いくつかの上位レベルのコードによって定期的に呼び出されます。バックグラウンドスレッドからココアメッセージループをポップする

メインスレッドですべてを実行すると、ビューが入力イベントを正しく受信するという点で問題なく動作します。

代わりに、ウィンドウの作成とメッセージループを別のスレッドに移動すると、nextEventMatchingMaskはイベントを返さなくなり、ビューは入力を受け取りません。

私は、Cocoaアプリケーションの「メイン」スレッドだけがイベントを処理することになっていることを認識しています。しかし、このセカンダリスレッドはCocoaと話す必要がある唯一のスレッドなので、Cocoaに関する限り、これを「メイン」スレッドとして使用したいと考えています。これは可能ですか?私はこのスレッドからNSApplicationLoadを呼び出し、私が知っている限り、これはプロセスで呼び出された最初のCocoa関数です。

メインのCocoaスレッドを指定できない場合は、バックグラウンドスレッドでNSWindowを作成してイベントを受け取る他の方法はありますか?私はアプリケーションのメインループを制御していないので、NSApplication Runを呼び出すようなことはできません。私は、ウィンドウから入力イベントを取得する必要があります。

+0

この:http://stackoverflow.com/questions/6178618/mac-os-x-is-it-possible-to-imbue-a-non私の状況とまったく同じようにメインスレッドになるメインスレッドとなる。 – eodabash

答えて

3

2次スレッドでrunloopを開始する必要があるかもしれません。これはあなたのスレッド実行ループ処理のイベントを開始する必要があります

+ (void)launchThread 
{ 
    NSRunLoop *threadRunLoop = [NSRunLoop currentRunLoop]; 
    while (someThreadExitCondition && [threadRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]); 
} 

:のようなものを持って、ThreadHandlerクラスで

[NSThread detachNewThreadSelector:@selector(launchThread) 
         toTarget:[ThreadHandler class] 
         withObject:nil]; 

:あなたのセカンダリスレッドをオフに産卵あなたのメインスレッドでは、このような何かを呼び出します。私は、これがセカンダリスレッドで作成されたウィンドウのイベントを処理できるようにするかどうかテストすることなく、スレッドのrunloopを実行する方法を開始するかもしれません。メインイベントループからNSConnectionを経由してセカンダリスレッド(example)にイベントをポンピングする分散オブジェクトのようなものを設定することもできます。うまくいけば、これは少なくともあなたに追求する別の道を与えるかもしれない。

+0

提案していただきありがとうございます。ただし、この2番目のスレッドはNSThreadではなくposixスレッドであり、私の管理下にありません。イベントをチェックしたいので、私が作業しているコードを定期的に呼び出すので、ブロッキングループを入力することはできません。たぶん私は自分のイベント処理スレッドを記述するようにしても構いませんが、イベント処理を行っていると思うスレッドに処理されたイベントをマーシャリングして戻すことができます。 – eodabash

1

これは私が頼りにする行動ではありません。

実行ループによって制限されていないスレッドでバックエンドを実行する必要がある場合は、メインスレッドからUIを実行するためにセカンダリスレッドでバックエンドを実行します。

また、あなたが別のプロセスを作成することができます...

関連する問題