CFWriteStreamScheduleWithRunLoop有时会起作用,有时候不行吗?

时间:2010-12-09 16:43:45

标签: sockets ios runloop

我正在进行异步套接字编程,而且我的代码大部分时间都可以工作,但有时却没有。要点是:我创建一个套接字对,创建读写流,然后当我想写一些东西时,我在一个单独的线程的运行循环上安排它。像这样:

CFStreamClientContext context = {0, sc, NULL, NULL, NULL};
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) {
 CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}

...其中myWriteStreamCallback是正确形式的静态函数...

套接字/流如此打开:

CFReadStreamRef readStream  = NULL;
CFWriteStreamRef writeStream = NULL; 

@try {
   // create a pair of streams to the host and open them

  CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, scomm.host, SERVER_PORT, &readStream, &writeStream);
  if (readStream == NULL)     @throw [[[CommunicationReadStreamNotCreatedException alloc] init] autorelease];
  if (writeStream == NULL)    @throw [[[CommunicationWriteStreamNotCreatedException alloc] init] autorelease];
  if (!CFReadStreamOpen(readStream))  @throw [[[CommunicationReadStreamNotOpenedException alloc] init] autorelease];
  if (!CFWriteStreamOpen(writeStream)) @throw [[[CommunicationWriteStreamNotOpenedException alloc] init] autorelease];
  ...

现在问题出现了:这个代码(还有更多,如果它能帮助任何人),大多是正确的,因为它主要起作用。但是,有时候,在程序的最开始,我可以尝试以这种方式发送一些数据,并且套接字的回调将正确地放在运行循环上,但是它永远不会被调用。稍后在程序中,相同的代码将与另一个套接字一起运行,并且将调用回调(套接字转到同一地址)。

我知道这很模糊,但在我发布所有代码之前,是否有人对可能导致这种情况的事情有任何粗略的想法?回调有时没有在runloops上调用,即。

哦是的,我应该补充一点,这显然是某种竞争条件 - 我可以通过在正确的位置添加日志记录来不可靠地解决问题。然后,它有时会工作,有时则不会,使用完全相同的代码。有趣的。

1 个答案:

答案 0 :(得分:1)

我在苹果论坛上获得了“quinn the eskimo”的解决方案:

问题是在一个线程中完成的主机解析和其他线程中使用的CFHostRef。这是不好的。

在同一个线程(上面的CFHost对象)中完成的

scomm.host创建修复了问题。