调用CFReadStreamRead会在线程中停止执行

时间:2012-04-16 15:54:36

标签: ios nsthread core-foundation cfstream

  

NB:此项目的整个代码库是如此之大,以至于发布任何有意义的数量都会导致此问题过于本地化,我试图将任何代码提炼为基本要素。我不希望任何人直接解决我的问题,但我会投票给那些我觉得有帮助或有趣的答案。

此项目使用AudioStreamer的修改版本来播放保存到本地设备(iPhone)的音频文件。

使用此代码在当前循环中设置和调度流(据我所知,从标准AudioStreamer项目未改变):

CFStreamClientContext context = {0, self, NULL, NULL, NULL};
CFReadStreamSetClient(
                          stream,
                          kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
                          ASReadStreamCallBack,
                          &context);
CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

ASReadStreamCallBack来电:

- (void)handleReadFromStream:(CFReadStreamRef)aStream
               eventType:(CFStreamEventType)eventType

在AudioStreamer对象上,这一切都正常,直到使用以下代码读取流:

BOOL hasBytes = NO;  //Added for debugging
hasBytes = CFReadStreamHasBytesAvailable(stream);

length = CFReadStreamRead(stream, bytes, kAQDefaultBufSize);

hasBytesYES但是当CFReadStreamRead被称为执行停止时,应用程序不会崩溃它只是停止激动,CFReadStreamRead调用以下的任何断点都没有被击中并且不再调用ASReadStreamCallBack

我对可能造成这种情况感到茫然,我最好的猜测是线程被终止了?但是,我和他们一直在问这个原因。

之前有没有人见过这种行为?如何追踪它以及如何解决它的想法将非常受欢迎!

通过评论请求的其他信息

  1. 这是100%可重复的
  2. 我添加了
  3. CFReadStreamHasBytesAvailable进行调试但删除它没有效果

2 个答案:

答案 0 :(得分:2)

首先,我假设CFReadStreamScheduleWithRunLoop()CFReadStreamRead()在同一个主题上运行?

这个线程处理它的runloop吗?不这样做是我的主要怀疑。你在这个帖子上有CFRunLoopRun()或类似的电话吗?

通常没有理由产生一个单独的线程来异步读取流,所以我对你的线程设计有点困惑。这里有真正的后台线程吗?此外,通常CFReadStreamRead()会在您的客户端回调中(当您收到kCFStreamEventHasBytesAvailable事件时(它似乎在链接代码中),但您建议永远不会调用ASReadStreamCallBack你是如何修改AudioStreamer的?

答案 1 :(得分:0)

流指针可能在某种程度上损坏了。如果字节可用,CFReadStreamRead肯定不会阻塞(对于本地文件,它肯定永远不会阻塞超过几毫秒)。您能提供用于创建流的代码吗?

或者,CFReadStreams以异步方式发送消息,但由于没有处理runloop,因此可能(但不太可能)阻塞它。

如果您愿意,我已经上传了我的AudioPlayer,其灵感来自于https://code.google.com/p/audjustable/托管的Matt的AudioStreamer。它支持本地文件(以及HTTP)。我认为它可以满足您的需求(不只是来自HTTP的流文件)。