对 CFReadStreamRead 的调用会停止线程中的执行



注意:这个项目的整个代码库是如此之大,以至于发布任何有意义的内容都会使这个问题过于本地化,我试图将任何代码提炼到最基本的内容。我不指望有人直接解决我的问题,但我会投票给那些我认为有帮助或有趣的答案。

此项目使用修改版本的 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);

hasBytes YES但是当CFReadStreamRead调用时,执行停止,应用程序不会崩溃,它只是停止刺激,CFReadStreamRead调用以下的任何断点都不会命中,并且不会再次调用ASReadStreamCallBack

我不知道是什么原因导致这种情况,我最好的猜测是线程正在终止?但是如何和为什么是我问的原因。

以前有人见过这种行为吗?我如何追踪它,关于如何解决它的想法将非常受欢迎!

通过评论请求的其他信息

  1. 这是100%可重复的
  2. CFReadStreamHasBytesAvailable是我添加的用于调试,但删除它不起作用

首先,我假设CFReadStreamScheduleWithRunLoop()CFReadStreamRead()在同一线程上运行?

此线程是否正在处理其运行循环?不这样做是我的主要怀疑。您在此线程上有类似 CFRunLoopRun() 或等效的调用吗?

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

流指针可能只是以某种方式损坏。 如果字节可用,CFReadStreamRead 当然不应该阻塞(对于本地文件,它肯定不会阻塞超过几毫秒)。 能否提供用于创建流的代码?

或者,CFReadStreams 异步发送消息,但有可能(但不太可能)阻塞,因为未处理运行循环。

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

相关内容

  • 没有找到相关文章

最新更新