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);
hasBytes
是YES
但是当CFReadStreamRead
被称为执行停止时,应用程序不会崩溃它只是停止激动,CFReadStreamRead
调用以下的任何断点都没有被击中并且不再调用ASReadStreamCallBack
。
我对可能造成这种情况感到茫然,我最好的猜测是线程被终止了?但是,我和他们一直在问这个原因。
之前有没有人见过这种行为?如何追踪它以及如何解决它的想法将非常受欢迎!
CFReadStreamHasBytesAvailable
进行调试但删除它没有效果答案 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的流文件)。