问题描述
我正在使用第三方框架在Swift中编写命令行应用程序(如果我正确理解代码),当套接字接收数据时,该框架依赖GCD回调来完成某些操作.为了更好地理解该框架,我一直在研究该框架的作者与该框架一起编写的示例Cocoa应用程序.
I am writing a command line application in Swift using a third-party framework that (if I understand the code correctly) relies on GCD callbacks to complete certain actions when a socket receives data. In order to better understand the framework, I have been playing around with a sample Cocoa application the framework's author wrote to go along with the framework.
因为示例应用程序是Cocoa应用程序,所以运行循环是自动处理的.我包括示例应用程序(MIT许可证)中的代码片段,以提供有关其工作原理的想法:
Because the sample application is a Cocoa application, the run loops are handled automatically. I'm including snippets of code from the sample application (MIT license) to give an idea of how it works:
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))
...
httpd.listen(1337)
}
...
func applicationDidFinishLaunching(aNotification: NSNotification?) {
startServer()
...
}
}
我想修改示例应用程序以从命令行运行.当我将startServer()函数放入命令行应用程序时,它将运行,但是套接字在打开后立即关闭,并且该程序以退出代码0结束执行.这是预期的行为,因为没有运行循环在Xcode命令行项目中,因此程序不知道等待套接字接收数据.
I'd like to modify the sample application to run from the command line. When I put the startServer() function into a command line application, it runs, but the socket is immediately closed after it is opened, and the program finishes executing with an exit code 0. This is expected behavior, as there are no run loops in an Xcode command line project, and thus the program doesn't know to wait for the socket to receive data.
我相信使套接字保持打开状态和使程序连续运行的正确方法是将主线程放入CFRunLoop中.我查看了Apple的文档,除了基本的API参考外,Swift中的线程没有任何内容.我看过第三方资源,但是它们都涉及iOS和Cocoa应用程序中的备用线程.如何为主线程正确实现CFRunLoop?
I believe the correct way to get the socket to stay open and the program to continuously run would be to put the main thread in a CFRunLoop. I have looked over Apple's documentation and, except for the basic API reference, there is nothing on threading in Swift. I have looked at third party resources, but they all involve alternate threads in iOS and Cocoa applications. How do I properly implement a CFRunLoop for the main thread?
推荐答案
NSRunLoop类参考有一个简单的运行循环示例:
The NSRunLoop Class Referencehas an example for a simple runloop:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
可以翻译成Swift:
which can be translated to 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) { }
或
dispatchMain()
这篇关于Swift命令行程序中的CFRunLoop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!