0

NSTask内からを起動しようとしているときに に遭遇しましたNSOperation

これは、問題を紹介するためにまとめた非常に単純なアプリです。ボタンをクリックすると、NSOperationがキューに入れられます。をセットアップしNSRunLoop、 を呼び出すメソッドを呼び出しますNSTask。タスクは非常に単純です。2 秒間起動するだけ/bin/sleepです (正常に動作しているときにスピナーを簡単に確認するのに十分な時間です)。

アプリは宣伝どおりに動作しますが、TaskPerformer.m の 23 行目をautorelease, (申し訳ありませんが、私は新しい投稿者なので、直接リンクできません) に変更するか、完全にコメントアウトすると (NSTaskオブジェクトがリークします)、NSOperation「 s スレッドは決して終了しません。メインの実行ループが何かをブロックしているようです。

さて、ここでの問題は 2 つあります。まず、スレッドがブロックされている理由がわかりませんが、さらに、このアプリケーションのガベージ コレクションをオンにすると、同じ動作が現れます。を手動で解放する方法がないためNSTask、スレッドは何があってもブロックされます。

誰かが私に何が起こっているのか教えてくれたら、私は永遠に感謝します!

4

2 に答える 2

4

あなたが投稿したサンプル プロジェクトには、いくつかの異なる問題が見られます。TaskPerformer.m には次のものがあります。

[task waitUntilExit];
[task launch];

このwaitUntilExit呼び出しは、タスクの起動に呼び出されることを意図しており、タスクが完了するまで単にブロックして何もしません。タスクが終了するまで待機するだけで、タスクから出力を取得することなど気にしない場合は、 を呼び出してから を呼び出すだけでよく、実行ループをいじる必要はまったくありませんlaunchwaitUntilExit

ただし、タスクから出力を取得したい場合は、その を取得する必要があります。standardOutputこれは、デフォルトで のインスタンスを返す必要がありますNSFileHandlereadDataOfLength:その後、またはを呼び出すことができます。これらreadDataToEndOfFileはどちらもブロックし、データが利用可能な場合にプロセスからデータを返します。

いずれにせよ、このすべてがバックグラウンド スレッドで実行されるため、これらのメソッドがブロックされても問題ありませんが、メイン スレッドで同じことを実行したくないでしょう。タスクが完了しました。メイン スレッドでこれを行った場合は、 とフレンズを使用する必要がNSFileHandleありreadInBackgroundAndNotifyます。ただし、バックグラウンド スレッドの場合は、を使用するNSRunLoop必要はありません。

于 2010-07-21T15:32:45.470 に答える
1

ここで何が起こっているのかを理解しました。私の呼び出し[runLoop run]は、ループを設定して無期限に実行していたことがわかりました。while (!done)ループに陥ることはありませんでした。を呼び出した後runNSRunLoopは入力がなくなるまで実行されます。release私の呼び出しはNSTaskまさにこのシナリオにつながったので、(まったく偶然に)私のランループは終了しました。

[runLoop run]解決策は、自分のwhileループを削除して単純に依存することでした。これが他の誰かに役立つことを願っています!

于 2010-07-22T17:55:18.940 に答える