私はGCDAsyncSocketで動作する簡単な例を取得しようとしていますが、理解が不足していることを発見しました。すばらしい人々がこれを説明するのを手伝ってくれることを願っています。
以下にGCDAsyncSocketを設定しました。
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
NSString *host = @"192.168.169.132";
uint16_t port = 2112;
DDLogInfo(@"Connecting to \"%@\" on port %hu...", host, port);
self.viewController.label.text = @"Connecting...";
NSError *error = nil;
if (![asyncSocket connectToHost:host onPort:port withTimeout:5.0 error:&error])
{
DDLogError(@"Error connecting: %@", error);
self.viewController.label.text = @"Oops";
}
else
{
DDLogVerbose(@"Connecting...");
}
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
DDLogInfo(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
self.viewController.label.text = @"Connected";
// We're just going to send a test string to the server.
NSString *myStr = @"testing...123...\r\n";
NSData *myData = [myStr dataUsingEncoding:NSUTF8StringEncoding];
[asyncSocket writeData:myData withTimeout:5.0 tag:0];
}
そして、私のソケットテストサーバーアプリが文字列を受信するのを見ることができます
「テスト中...123... \ r \n」
しかし、ソケットテストサーバーに文字列を返送させると、didReadDataデリゲートが実行されることを素朴に期待していました
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
それでも、冷酷な現実は私が電話するまで私にそれを学ばせました
[asyncSocket readDataWithTimeout:5.0 tag:0];
... didReadDataデリゲートは呼び出されません。
OK、それは大丈夫です。わかった。
ドキュメントをもう少し読むと、それは明確に次のように述べています
AsyncSocketは、RunLoopベースのTCPソケットライブラリです。
だから今、私はこのRunLoopのものを見ています。これは、私の見解では、MicrosoftWindowsのメッセージループのようなものです。iOSはイベント/メッセージ駆動型アーキテクチャ(Win32と同様)であるため、現在使用しているデフォルトのメインスレッドには、イベントを処理するための独自のmsgループがあります。
私の混乱は、iOS RunLoopが、GCDAsyncSocketを正しく機能させるために連携しなければならない別のエンティティのように見えることです。
実行ループモードのデフォルトセットがNSDefaultRunLoopModeであると述べている場合、これはメインスレッドにあります。
まだ混乱していますか?
したがって、Win32では、通信イベント処理コードは次のようになります。
while( sCOMport.hCOMport != INVALID_HANDLE_VALUE ) // ...while the COM port is open...
{
// Wait for an event to occur on the port.
WaitCommEvent( sCOMport.hCOMport, &dwCommStatus, NULL );
もちろん、それは独自のスレッドにあります(GCDAsyncSocketを使用してまだそこに到達していません)が、それはある意味で独自の「RunLoop」になります。
[asyncSocket readDataWithTimeout]呼び出しでキューを埋めるポーリングループでスタックしないように、GCDAsyncSocketを使用して同じことを行うにはどうすればよいですか?
このライブラリを使用するには、より良い例が必要だと思います。