9

ソケットがデータを受信したときに特定のアクションを完了するために、(コードを正しく理解していれば) 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 を適切に実装するにはどうすればよいですか?

4

2 に答える 2

7

NSRunLoop クラス リファレンス には、単純な実行ループの例があります。

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) { }

また

dispatchMain()
于 2014-08-04T20:20:48.530 に答える
7

Martin Rの答えはうまくいくはずですが、1回の関数呼び出しでソケットを開いたままにすることができました。startServer() 関数の最後に、次の行を追加します。

CFRunLoopRun()

これはうまくいきました。

于 2014-08-04T20:25:43.393 に答える