【发布时间】:2013-09-24 15:42:33
【问题描述】:
我看到一个问题,其中CFReadStreamRead,作为流式文件上传的一部分,从不返回。
这种情况似乎只发生在 iOS7 上 — 在物理设备上进行调试时比在模拟器中更频繁 — 或者至少,在那里更为明显。
我们有一个文件的 HTTP(或 HTTPS,问题发生在任何一种方式,使用本地托管或远程服务器)POST,通过直线阻塞(非事件驱动)CFNetwork 调用。这是 C 代码调用这个处理程序的必要条件;没有回调的规定。
很好,网络调用发生在后台线程和/或通过异步调度。
有问题的网络代码归结为(为简洁起见,删除错误处理):
CFReadStreamRef upload = CFReadStreamCreateWithFile(
kCFAllocatorDefault, upload_file_url);
CFRelease(upload_file_url);
CFReadStreamOpen(upload);
CFReadStreamRef myReadStream = CFReadStreamCreateForStreamedHTTPRequest(
kCFAllocatorDefault, myRequest, upload);
CFReadStreamOpen(myReadStream);
CFIndex numBytesRead = CFReadStreamRead(myReadStream, buf, sizeof(buf));
// etc.
就其本身而言,这段代码想在 iOS7 下立即挂起。如果我在它之前添加一个对usleep 的调用的循环(沿途检查CFReadStreamHasBytesAvailable),它将几乎总是成功。每隔几百次尝试,它仍然会失败,永远不会返回。同样,主线程不受影响。
我希望 GM 能清除这种行为,但它仍然存在。
添加一个 runloop/callback 方法来监视字节可用事件没有任何效果 - 当调用挂起时,也看不到任何事件。
关于为什么会发生这种情况或如何防止这种情况的任何建议?还有其他人在 iOS 7 下看到不同的 CFReadStream 行为吗?
【问题讨论】:
-
我有类似的问题:如果客户端在 iOS 7 下运行,服务器挂起并且客户端永远不会得到 HTTP 响应。iOS 3-4-5-6 很好。客户端使用 NSUrlConnection。任何人:请分享您的观察结果。
-
函数阻塞的原因有据可查。所以,第一个问题:你确定文件没有被完全读取并且它在中间的某个地方阻塞吗?其次,你确定文件已经打开成功了吗?
-
这两件事都是肯定的,并且完全期望该功能在需要时阻止。是的,(省略的)错误处理检查文件是否已正确打开。
-
您可能会添加更多代码。我假设您使用
CFReadStreamCreateForStreamedHTTPRequest将CFReadStream绑定到请求正文。我与 CFNetwork 合作的不多,但NSMutableURLRequest需要一个未打开的NSInputStream(当设置为 HTTPBodyStream 时)。所以我想知道您的 CFReadStream 在使用CFReadStreamCreateForStreamedHTTPRequest()设置之前是否必须打开。 -
文件读取流(上传)在调用
CFReadStreamCreateForStreamedHTTPRequest之前打开;myReadStream直到之后才存在。请注意,这不是“嘿,我的代码怎么不起作用?”它是“除非我先睡一段不确定的时间,否则我以前快乐的(并且非常基于 Apple 的示例)代码现在怎么会挂起?”
标签: ios ios7 cfnetwork cfreadstream