Swift GDC后台进程冻结应用程序

时间:2016-02-09 07:14:06

标签: swift cocoa background dispatch-async

我已经编写了启动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行正在运行。如何解决这个问题?

0 个答案:

没有答案