ソケットがデータを受信したときに特定のアクションを完了するために、(コードを正しく理解していれば) GCD コールバックに依存するサードパーティ フレームワークを使用して、Swift でコマンド ライン アプリケーションを作成しています。フレームワークをよりよく理解するために、フレームワークの作成者がフレームワークに合わせて作成した Cocoa アプリケーションのサンプルを試してみました。
サンプル アプリケーションは Cocoa アプリケーションであるため、実行ループは自動的に処理されます。サンプル アプリケーション (MIT ライセンス) のコード スニペットを含めて、どのように機能するかを示します。
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コマンドラインプロジェクトでは、プログラムはソケットがデータを受信するのを待つことを知りません。
ソケットを開いたままにし、プログラムを継続的に実行する正しい方法は、メインスレッドを CFRunLoop に入れることだと思います。私は Apple のドキュメントを調べましたが、基本的な API リファレンスを除いて、Swift でのスレッド化については何もありません。サードパーティのリソースを見てきましたが、それらはすべて iOS および Cocoa アプリケーションの代替スレッドに関係しています。メインスレッドに CFRunLoop を適切に実装するにはどうすればよいですか?