Swift - 如何在不让应用程序挂起的情况下等待某些事情
Swift - How to wait for something without making the app hanging
我有这样的代码:
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 { [=12=].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 { [=12=].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 的情况下不断寻找日志文件更改的同时实现 NSImage 和 NSLocalizedString 的可见更改(或者甚至使用挂起 GUI,但有足够的时间更改 while 循环之间的可见元素) ?
轮询文件系统资源是一种糟糕的做法。 不要那样做。有专门的 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
}
我有这样的代码:
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 { [=12=].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 { [=12=].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 的情况下不断寻找日志文件更改的同时实现 NSImage 和 NSLocalizedString 的可见更改(或者甚至使用挂起 GUI,但有足够的时间更改 while 循环之间的可见元素) ?
轮询文件系统资源是一种糟糕的做法。 不要那样做。有专门的 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
}