task already launchedエラー

ParanoiaImportは内部でProcess()と呼ばれる機能を多用している。Objective-CでNSTask()と呼ばれたもので、Unixバイナリなどを子プロセスとして起動する。

今回、ParanoiaImportに処理の停止機能をつけようとして、task already launchedエラーに苦しんだ。と言っても3日くらいの話だが…。

どういう状況だったかというと、開始ボタンのアクションで子プロセスを起動、停止ボタンで起動した子プロセスを停止するというコードを書いたのに、開始ボタンを押し、それから停止ボタンを押し、再び開始ボタンを押すとtask already launchedエラーになるというものだった。

Appleのドキュメントにも、An Process object can only be run once. Subsequent attempts raise an error.とは書いてある。
この記事にも、タスクが実行中にも関わらず再度launch()を実行してしまうと、下記の実行エラーが発生してしまう。と書いてある。だが、今一つ腑に落ちなかった。

悩むこと3日、もう一度Appleのドキュメントをじっと見つめていた時、天恵が開いた。

元々のコード

class ViewController: NSViewController, NSWindowDelegate {

	@IBAction func startButton(_ sender: Any) {
	    let paranoiaTask = Process()
	    paranoiaTask.launchPath = self.getParanoiaPath()
	    paranoiaTask.currentDirectoryPath = aiffDir
	    paranoiaTask.arguments = ["-qBf"]
	    paranoiaTask.launch()
	    paranoiaTask.waitUntilExit()
	}
}

実行エラーを発生するコード

 var paranoiaTask = Process()
 
class ViewController: NSViewController, NSWindowDelegate {

	@IBAction func startButton(_ sender: Any) {
		
	    paranoiaTask.launchPath = self.getParanoiaPath()
	    paranoiaTask.currentDirectoryPath = aiffDir
	    paranoiaTask.arguments = ["-qBf"]
	    paranoiaTask.launch()
	    paranoiaTask.waitUntilExit()
	}
	
	@IBAction func startButton(_ sender: Any) {
		
		paranoiaTask.terminate()
	}
}

対策したコード

var paranoiaTask = Process()
 
class ViewController: NSViewController, NSWindowDelegate {

	@IBAction func startButton(_ sender: Any) {
		
	    paranoiaTask = Process()
	    paranoiaTask.launchPath = self.getParanoiaPath()
	    paranoiaTask.currentDirectoryPath = aiffDir
	    paranoiaTask.arguments = ["-qBf"]
	    paranoiaTask.launch()
	    paranoiaTask.waitUntilExit()
	}
	
	@IBAction func startButton(_ sender: Any) {
		
		paranoiaTask.terminate()
	}
}

気が付いてみれば、ポカミスの類に属することなのだが、実行エラーを発生するコードでは、タスク起動時に初期化していない。すなわち2回目以降の起動はAppleのドキュメントにある多重起動に当たる。

Subsequent attemptsというのがどういう事かあまりに資料がないので、恥をかなぐり捨てて記事を書いた。穴があったら入りたい気分である…。

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL