当您意识到自己不知道发生了什么时那种沉没的感觉...
我已经在网络代码中使用此代码近两年了,没有出现任何问题。
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)至少在我的代码中,CFReadStreamOpen似乎总是返回false。 The documentation有点令人困惑,但我读它的意思是该流尚未打开,但稍后会在运行循环中打开。
2)我进行的大多数调用都发生在运行循环已经在运行的主线程中,因此不需要调用CFRunLoopRun。给我带来问题的调用发生在一个块内,这显然产生了一个新线程。这个新线程不会启动新的运行循环-因此,除非我明确运行新线程的运行循环,否则流永远不会打开。
我仍然不太了解如果我在已经运行了运行循环的线程上调用CFRunLoopRun()会发生什么,但是显然不好。
最后,我放弃了自制的网络代码,转而使用了我一直想做的ASIHTTPRequest。
关于iphone - 关于CFNetwork,CFReadStreamOpen和CFRunLoopRun的困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7507497/