CFReadStreamRead 在 iOS 7 下永久阻塞



>我看到一个问题,其中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/回调方法来监视字节可用事件不起作用 - 当调用挂起时,也不会看到任何事件。

关于为什么会发生这种情况或如何防止它的任何建议?还有其他人在 iOS 7 下看到不同的CFReadStream行为吗?

我已经尝试了这种令人讨厌的解决方法,它对我有用,问题是我正在从服务器请求增量值,所以如果出现问题,我只是获取新的增量值,一般来说它不起作用(在日志中我看到超时有时会启动)。至少这可以防止形成永久线程阻塞,并有机会以某种方式处理此问题:

NSInteger readStreamReadWorkaround(CFReadStreamRef readStrem, UInt8 *buffer, CFIndex bufferLength) {
  static dispatch_once_t onceToken;
  static BOOL isProblematicOs = YES;
  dispatch_once(&onceToken, ^{
    isProblematicOs = [[UIDevice currentDevice].systemName compare: @"7.0" options: NSNumericSearch]!=NSOrderedAscending;
  });
  NSInteger readBytesCount = -2;
  if (isProblematicOs) {
    CFStreamStatus sStatus = CFReadStreamGetStatus(readStrem);
    NSDate *date = [NSDate date];
    while (YES) {
      if(CFReadStreamHasBytesAvailable(readStrem)) {
        readBytesCount = CFReadStreamRead(readStrem, buffer, bufferLength);
        break;
      }
      sStatus = CFReadStreamGetStatus(readStrem);
      if (sStatus!=kCFStreamStatusOpen && sStatus !=kCFStreamStatusAtEnd
          || [date timeIntervalSinceNow]<-15.0) {
        break;
      }
      usleep(50000);
    }
  } else {
    readBytesCount = CFReadStreamRead(readStrem, buffer, sizeof(buffer));
  }
  return readBytesCount;
}

我不喜欢这个解决方案,但到目前为止,我没有看到替代方案。

相关内容

  • 没有找到相关文章

最新更新