Swift-如何在不挂起应用程序的情况下等待

时间:2019-06-24 07:45:32

标签: swift macos while-loop wait

我有这样的代码:

    print("Migration Execution: Successfully uninstalled MCAfee")
    migrationInfoPicture.image = NSImage(named: "Unroll")
    migrationInfoText.stringValue = NSLocalizedString("Unrolling from old server... Please wait!", comment: "Unrolling")
    while(!readFile(path:logfilePath)!.contains("result: 2 OK")) {
        searchLogForError(scriptPath: scriptOnePath)
    }
    print("Migration Execution: Successfully unrolled from old server")
    migrationInfoText.stringValue = NSLocalizedString("Setting up MDM profile... Please wait!", comment: "Setting up MDM")
    while(!readFile(path:logfilePath)!.contains("result: 3 OK")) {
        searchLogForError(scriptPath: scriptOnePath)
    }

它实际上是在后台运行的,可以从文件中读取文件和进行日志记录,但是由于GUI会挂起执行带有快速完成任务的while循环,因此图像和文本更改将不可见。

searchForLogError的代码是:

func searchLogForError(scriptPath:String) {
    if((readFile(path:logfilePath)!.filter { $0.contains("ERROR") }).contains("ERROR")) {
        print("Migration abborted")
        migrationInfoPicture.image = NSImage(named: "FatalError")
        migrationInfoText.stringValue = NSLocalizedString("An error occured: \n", comment: "Error occurence") + readFile(path:logfilePath)!.filter { $0.contains("ERROR") }[0]
        migrationWarningText.stringValue = NSLocalizedString("In order to get further help, please contact: mac.workplace@swisscom.com", comment: "Error support information")
        self.view.window?.level = .normal
        btnExitApplicationOutlet.isHidden = false
        getScriptProcess(path:scriptPath).terminate()
        return
    }
}

如何在不挂起GUI(甚至挂起GUI,但有足够的时间在while循环之间更改可见元素)的情况下不断寻找日志文件更改的同时,如何实现NSImage和NSLocalizedString的可见更改? / p>

1 个答案:

答案 0 :(得分:1)

轮询文件系统资源是一种可怕的做法。 不要这样做。有专用的API可观察文件系统资源,例如DispatchSourceFileSystemObject

创建属性

var fileSystemObject : DispatchSourceFileSystemObject?

和两种启动和停止观察器的方法。在setEventHandler的结尾处,插入代码以读取文件

func startObserver(at url: URL)
{
    if fileSystemObject != nil { return }

    let fileDescriptor : CInt = open(url.path, O_EVTONLY);
    if fileDescriptor < 0  {
        print("Could not open file descriptor"))
        return
    }
    fileSystemObject = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: [.write, .rename], queue: .global())

    if fileSystemObject == nil {
        close(fileDescriptor)
        print"Could not create Dispatch Source"))
        return
    }
    fileSystemObject!.setEventHandler {
        if self.fileSystemObject!.mask.contains(.write) {
           // the file has been modified, do something

        }
    }
    fileSystemObject!.setCancelHandler {
        close(fileDescriptor)
    }
    fileSystemObject!.resume()
}

func stopObserver()
{
   fileSystemObject?.cancel()
   fileSystemObject = nil
}