3

当你意识到自己不知道发生了什么时,那种下沉的感觉……

我在我的网络代码中使用这个代码已经快两年了,没有任何问题。

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 调用在上述代码中实际上做了什么?为什么示例代码会进行该调用 - 如果此代码在主线程中运行,我不应该运行运行循环?

4

1 回答 1

1

我想我会尽可能多地回答我自己的问题。

1) 至少在我的代码中,CFReadStreamOpen 似乎总是返回 false。 文档有点混乱,但我读到它意味着流尚未打开,但稍后会在运行循环中打开。

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

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

我最终放弃了自制的网络代码并切换到 ASIHTTPRequest,无论如何我都在考虑这样做。

于 2011-09-29T15:19:23.330 回答