Swift命令行程序中的CFRunLoop
我正在使用第三方框架用Swift编写一个命令行应用程序,该框架(如果我正确理解代码)在套接字接收数据时依赖GCD回调来完成某些操作。为了更好地理解该框架,我一直在使用该框架作者为配合该框架而编写的示例Cocoa应用程序 因为示例应用程序是Cocoa应用程序,所以运行循环是自动处理的。我将包含示例应用程序(MIT许可证)中的代码片段,以了解其工作原理:Swift命令行程序中的CFRunLoop,swift,grand-central-dispatch,cfrunloop,Swift,Grand Central Dispatch,Cfrunloop,我正在使用第三方框架用Swift编写一个命令行应用程序,该框架(如果我正确理解代码)在套接字接收数据时依赖GCD回调来完成某些操作。为了更好地理解该框架,我一直在使用该框架作者为配合该框架而编写的示例Cocoa应用程序 因为示例应用程序是Cocoa应用程序,所以运行循环是自动处理的。我将包含示例应用程序(MIT许可证)中的代码片段,以了解其工作原理: class AppDelegate: NSObject, NSApplicationDelegate { var httpd : Conn
class AppDelegate: NSObject, NSApplicationDelegate {
var httpd : Connect!
func startServer() {
httpd = Connect()
.onLog {
[weak self] in // unowned makes this crash
self!.log($0)
}
.useQueue(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
我想修改示例应用程序以从命令行运行。当我将startServer()函数放入命令行应用程序时,它会运行,但套接字打开后会立即关闭,程序执行完毕,退出代码为0。这是预期的行为,因为Xcode命令行项目中没有运行循环,因此程序不知道等待套接字接收数据
我相信让套接字保持打开状态并让程序持续运行的正确方法是将主线程放入CFRunLoop中。我查阅了苹果的文档,除了基本的API参考,Swift中没有关于线程的内容。我看过第三方资源,但它们都涉及iOS和Cocoa应用程序中的备用线程。如何为主线程正确实现CFRunLoop?
有一个简单运行循环的示例:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
可翻译为Swift:
var shouldKeepRunning = true // global
let theRL = NSRunLoop.currentRunLoop()
while shouldKeepRunning && theRL.runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture()) { }
或者,只要打个电话就足够了
dispatch_main()
Swift 3.1的更新:
let theRL = RunLoop.current
while shouldKeepRunning && theRL.run(mode: .defaultRunLoopMode, before: .distantFuture) { }
或
看起来Martin R的答案应该是可行的,但是我通过一个函数调用就可以让套接字保持打开状态。在startServer()函数的末尾,我写了一行:
CFRunLoopRun()
这起作用了 事实上,
RunLoop.current()
现在是一个var
,所以它应该是RunLoop.current
调用此函数后如何结束运行循环?我算出了:CFRunLoopStop(CFRunLoopGetMain())
let theRL = RunLoop.current
while shouldKeepRunning && theRL.run(mode: .defaultRunLoopMode, before: .distantFuture) { }
dispatchMain()
CFRunLoopRun()