Seb*_*nik 7 runloop cocoaasyncsocket
我正在尝试使用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];
}
Run Code Online (Sandbox Code Playgroud)
并且可以看到我的套接字测试服务器app收到字符串
"测试... ... 123\r \n"
但是当我让我的套接字测试服务器发回一个字符串时,我天真地期望didReadData委托执行
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
Run Code Online (Sandbox Code Playgroud)
然而,冷酷的现实迫使我学习,直到我打电话
[asyncSocket readDataWithTimeout:5.0 tag:0];
Run Code Online (Sandbox Code Playgroud)
... 不会调用didReadData委托.
好没关系.我知道了.
阅读文档更清楚地说明了这一点
AsyncSocket是一个基于RunLoop的TCP套接字库.
所以现在我正在看这个RunLoop的东西,在我看来就像是Microsoft Windows中的Message循环.由于iOS是一个事件/ msg驱动架构(就像Win32一样),那么我目前所处的默认主线程显然拥有自己的msg循环来处理事件.
我的困惑现在让iOS RunLoop看起来像是一个独立的实体,必须使GCDAsyncSocket正常工作.
当它声明其默认的运行循环模式集是NSDefaultRunLoopMode时,它位于主线程中.
困惑了吗?
所以在Win32下我的comm事件处理代码如下所示:
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 );
Run Code Online (Sandbox Code Playgroud)
它当然会在它自己的线程中(还没有使用GCDAsyncSocket),但在某种程度上它将是它自己的"RunLoop".
我如何使用GCDAsyncSocket执行相同的操作,以便我不会陷入某些轮询循环,使用[asyncSocket readDataWithTimeout]调用填充队列?
我觉得我们在使用这个库时需要更好的例子.
Seb*_*nik 18
好吧,我以某种方式工作了.
如果这违反某些"最佳做法",请告诉我.
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
// setup as normal...
// then ...
// Instigate the first read
[asyncSocket readDataWithTimeout:-1 tag:0];
.
.
}
Run Code Online (Sandbox Code Playgroud)
然后......当数据进来时......
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
// Do whatever you need to do with the data ...
.
.
.
// and at the end ...
.
.
// Always keep a 'read' in the queue.
[asyncSocket readDataWithTimeout:-1 tag:0];
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供RunLoop操作,而无需使用计时器或其他构造.并且可以包含在自己的线程中.(那仍然是TBD)
| 归档时间: |
|
| 查看次数: |
13837 次 |
| 最近记录: |