1

NB: The entire code base for this project is so large that posting any meaningful amount wold render this question too localised, I have tried to distil any code down to the bare-essentials. I'm not expecting anyone to solve my problems directly but I will up vote those answers I find helpful or intriguing.

This project uses a modified version of AudioStreamer to playback audio files that are saved to locally to the device (iPhone).

The stream is set up and scheduled on the current loop using this code (unaltered from the standard AudioStreamer project as far as I know):

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

The ASReadStreamCallBack calls:

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

On the AudioStreamer object, this all works fine until the stream is read using this code:

BOOL hasBytes = NO;  //Added for debugging
hasBytes = CFReadStreamHasBytesAvailable(stream);
        
length = CFReadStreamRead(stream, bytes, kAQDefaultBufSize);

hasBytes is YES but when CFReadStreamRead is called execution stops, the App does not crash it just stops exciting, any break points below the CFReadStreamRead call are not hit and ASReadStreamCallBack is not called again.

I am at a loss to what might cause this, my best guess is the thread is being terminated? But the hows and whys is why I'm asking SO.

Has anyone seen this behaviour before? How can I track it down and ideas on how I might solve it will be very much welcome!

Additional Info Requested via Comments

  1. This is 100% repeatable
  2. CFReadStreamHasBytesAvailable was added by me for debugging but removing it has no effect
4

2 回答 2

2

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

这个线程正在处理它的运行循环吗?未能做到这一点是我的主要怀疑。你CFRunLoopRun()在这个线程上有类似或同等的电话吗?

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

于 2012-04-16T16:26:18.880 回答
0

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

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

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

于 2012-06-06T15:29:22.867 回答