xcode 如何防止命令行工具在异步操作完成之前退出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31944011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to prevent a Command Line Tool from exiting before asynchronous operation completes
提问by codecowboy
In a swift 2 command line tool (main.swift), I have the following:
在 swift 2 命令行工具 (main.swift) 中,我有以下内容:
import Foundation
print("yay")
var request = HTTPTask()
request.GET("http://www.stackoverflow.com", parameters: nil, completionHandler: {(response: HTTPResponse) in
if let err = response.error {
print("error: \(err.localizedDescription)")
return //also notify app of failure as needed
}
if let data = response.responseObject as? NSData {
let str = NSString(data: data, encoding: NSUTF8StringEncoding)
print("response: \(str)") //prints the HTML of the page
}
})
The console shows 'yay' and then exits (Program ended with exit code: 0), seemingly without ever waiting for the request to complete. How would I prevent this from happening?
控制台显示 'yay' 然后退出(程序以退出代码结束:0),似乎从未等待请求完成。我将如何防止这种情况发生?
The code is using swiftHTTP
代码使用的是swiftHTTP
I think I might need an NSRunLoopbut there is no swift example
我想我可能需要一个NSRunLoop但没有快速的例子
采纳答案by skwashua
I realize this is an old question, but here is the solution I ended on. Using DispatchGroup.
我意识到这是一个老问题,但这是我结束的解决方案。使用DispatchGroup。
let dispatchGroup = DispatchGroup()
for someItem in items {
dispatchGroup.enter()
doSomeAsyncWork(item: someItem) {
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: DispatchQueue.main) {
exit(EXIT_SUCCESS)
}
dispatchMain()
回答by codecowboy
回答by Mike Vosseller
You can call dispatchMain()
at the end of main. That runs the GCD main queue dispatcher and never returns so it will prevent the main thread from exiting. Then you just need to explicitly call exit()
to exit the application when you are ready (otherwise the command line app will hang).
您可以dispatchMain()
在 main 的末尾调用。它运行 GCD 主队列调度程序并且永远不会返回,因此它将阻止主线程退出。然后您只需要exit()
在准备好时显式调用退出应用程序(否则命令行应用程序将挂起)。
import Foundation
let url = URL(string:"http://www.stackoverflow.com")!
let dataTask = URLSession.shared.dataTask(with:url) { (data, response, error) in
// handle the network response
print("data=\(data)")
print("response=\(response)")
print("error=\(error)")
// explicitly exit the program after response is handled
exit(EXIT_SUCCESS)
}
dataTask.resume()
// Run GCD main dispatcher, this function never returns, call exit() elsewhere to quit the program or it will hang
dispatchMain()
回答by thiagoh
Don't depend on timing.. You should try this
不要依赖时间..你应该试试这个
let sema = DispatchSemaphore(value: 0)
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_November_2010-1a.jpg")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
print("after image is downloaded")
// signals the process to continue
sema.signal()
}
task.resume()
// sets the process to wait
sema.wait()
回答by Vexy
If your need isn'tsomething that requires "production level" code but some quick experiment or a tryout of a piece of code, you can do it like this :
如果您的需要不是需要“生产级”代码而是一些快速实验或一段代码的试用,您可以这样做:
SWIFT 3
斯威夫特 3
//put at the end of your main file
RunLoop.main.run(until: Date(timeIntervalSinceNow: 15)) //will run your app for 15 seconds only
More info : https://stackoverflow.com/a/40870157/469614
更多信息:https: //stackoverflow.com/a/40870157/469614
Please notethat you shouldn't rely on fixed execution time in your architecture.
请注意,您不应依赖架构中的固定执行时间。
回答by Chris Karani
Swift 4: RunLoop.main.run()
斯威夫特 4: RunLoop.main.run()
At the end of your file
在您的文件末尾