2011-09-21 58 views
3

那下沉的感觉,当你意识到你不知道发生了什么事......我一直在使用这种代码在我的网络代码几乎两年没有问题混淆CFNetwork的,CFReadStreamOpen和CFRunLoopRun

if (!CFReadStreamOpen(myReadStream)) { 
    CFStreamError myErr = CFReadStreamGetError(myReadStream); 
    if (myErr.error != 0) { 
    // An error has occurred. 
     if (myErr.domain == kCFStreamErrorDomainPOSIX) { 
     // Interpret myErr.error as a UNIX errno. 
      strerror(myErr.error); 
     } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) { 
      OSStatus macError = (OSStatus)myErr.error; 
      } 
     // Check other domains. 
    } 
} 

我相信它最初基于这里给出的示例代码:

http://developer.apple.com/library/mac/#documentation/Networking/Conceptual/CFNetwork/CFStreamTasks/CFStreamTasks.html

我最近注意到,然而,一些连接失败,因为CFReadStreamOpen返回false,但错误代码是0在以上的链接更多一些盯着后,我注意到CFRunLoopRun()语句,并将其添加:

if (!CFReadStreamOpen(myReadStream)) { 
    CFStreamError myErr = CFReadStreamGetError(myReadStream); 
    if (myErr.error != 0) { 
    // An error has occurred. 
     if (myErr.domain == kCFStreamErrorDomainPOSIX) { 
     // Interpret myErr.error as a UNIX errno. 
      strerror(myErr.error); 
     } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) { 
      OSStatus macError = (OSStatus)myErr.error; 
      } 
     // Check other domains. 
    } else 
     // start the run loop 
     CFRunLoopRun(); 
} 

该固定吨他连接问题。然而,我的应用程序开始显示随机问题 - 界面有时不响应,或不绘制,文本字段不可编辑,这种东西。

我读过CFReadStreamOpen和运行循环(特别是,主运行循环运行自己,我不应该运行一个运行循环,除非我设置它自己在一个辅助线程 - 我据我所知,不是。)但是我仍然对上面实际发生的事情感到困惑。具体来说:

1)为什么CFReadStreamOpen有时返回FALSE和错误代码0?这实际上意味着什么?

2)在上面的代码中,CFRunLoopRun调用实际上做了什么?为什么示例代码会这样调用 - 如果此代码在主线程中运行,我不应该运行运行循环?

回答

1

我想我会尽我所能回答我自己的问题。

1)在我的代码中,至少CFReadStreamOpen总是返回false。 The documentation有点令人困惑,但我读到它意味着流尚未打开,但稍后会在运行循环中打开。

2)我所做的大部分调用都发生在主线程中,运行循环已经在运行,因此调用CFRunLoopRun是不必要的。给我带来问题的电话是在一个区块内发生的,这显然催生了一个新线程。这个新的线程没有启动一个新的运行循环 - 所以这个流永远不会打开,除非我明确地运行了新线程的运行循环。

如果我在一个已经运行的运行循环的线程上调用CFRunLoopRun()会发生什么情况,我仍然没有100%清楚,但它显然不是很好。

我最终放弃了自家酿造的网络代码并切换到了ASIHTTPRequest,我正在考虑这么做。