我已经编写了启动Tor进程的函数。这是一个在SIGTERM发送到它之前不会停止的过程,因此,为了避免app冻结,我在后台队列中运行此进程(Tor需要在应用程序启动时启动,并在应用程序终止时完成,并且用户需要做其他一些事情)。这是我发布Tor的代码:
func launchTor(hashedPassword hash : String) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
let task = NSTask()
task.launchPath = "/bin/bash"
print("Hashed password : \(hash)")
task.arguments = (["-c", "/usr/local/bin/tor HashedControlPassword \(hash)"])
let pipe = NSPipe()
task.standardOutput = pipe
let handle = pipe.fileHandleForReading
handle.waitForDataInBackgroundAndNotify()
let errPipe = NSPipe()
task.standardError = errPipe
let errHandle = errPipe.fileHandleForReading
errHandle.waitForDataInBackgroundAndNotify()
var startObserver : NSObjectProtocol!
startObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSFileHandleDataAvailableNotification, object: nil, queue: nil) { notification -> Void in
let data = handle.availableData
if data.length > 0 {
if let output = String(data: data, encoding: NSUTF8StringEncoding) {
print("Output : \(output)")
}
}
else {
print("EOF on stdout")
NSNotificationCenter.defaultCenter().removeObserver(startObserver)
}
}
var endObserver : NSObjectProtocol!
endObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification, object: nil, queue: nil) {
notification -> Void in
print("Task terminated with code \(task.terminationStatus)")
NSNotificationCenter.defaultCenter().removeObserver(endObserver)
}
var errObserver : NSObjectProtocol!
errObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification, object: nil, queue: nil) {
notification -> Void in
let data = errHandle.availableData
if (data.length > 0) {
if let output = String(data: data, encoding: NSUTF8StringEncoding) {
print("Error : \(output)")
NSNotificationCenter.defaultCenter().removeObserver(errObserver)
}
}
}
task.launch()
_ = NSNotificationCenter.defaultCenter().addObserverForName("AppTerminates", object: nil, queue: nil) {
notification -> Void in
task.terminate()
}
task.waitUntilExit()
}
}
当它启动时,一切正常,但随后整个应用程序冻结。当我停止应用时,我总是看到let data = handle.availableData
行正在运行。如何解决这个问题?