【发布时间】:2015-02-06 17:21:57
【问题描述】:
我有这段代码可以从 AudioFileID 读取数据到缓冲区中。
- (void)handle:(void *)aqData audioQueue:(AudioQueueRef) audioQueue buffer:(AudioQueueBufferRef) buffer
{
TestViewController *vc = (__bridge TestViewController *)aqData;
EDCAudioFile *file = vc.file;
UInt32 numPackets = file.numberOfPacketsToRead;
UInt32 numBytesReadFromFile;
OSStatus err = AudioFileReadPacketData(file.audioFile, NO, &numBytesReadFromFile, vc.mPacketDescs, file.currentPacket, &numPackets, buffer->mAudioData);
当我像这样在我的方法中声明一个局部变量时,一切正常
EDCAudioFile *file = vc.file;
OSStatus err = AudioFileReadPacketData(file.audioFile, NO, &numBytesReadFromFile, vc.mPacketDescs, file.currentPacket, &numPackets, buffer->mAudioData);
EDCAudioFile 是一个包含 AudioFileID 属性的类,如下所示:
@property (nonatomic, assign) AudioFileID audioFile;
但是当我把它改成
OSStatus err = AudioFileReadPacketData(vc.file.audioFile, NO, &numBytesReadFromFile, vc.mPacketDescs, file.currentPacket, &numPackets, buffer->mAudioData);
而 vc 包含此属性
@property (nonatomic, strong) EDCAudioFile *file;
它因 EXC BAD ACCESS 线程 1 地址 0x4 而崩溃。当我从模态视图控制器中选择一首歌曲时,该方法被调用,该方法创建一个具有 16 个缓冲区的音频队列并用音频数据填充它们。
for (int i=0; i < 16; i++) {
AudioQueueAllocateBuffer(self.mQueue, file.bufferByteSize, &_mBuffers[i]);
handleOutputBuffer((__bridge void*) self, self.mQueue, _mBuffers[i]);
}
...
static void handleOutputBuffer (void *aqData, AudioQueueRef audioQueue, AudioQueueBufferRef buffer)
{
TestViewController *vc = (__bridge TestViewController *)aqData;
[vc handle:aqData audioQueue:audioQueue buffer:buffer];
}
当 i=1 和 for i=0 OSStatus 报告错误时它确实会崩溃,代码如下:2003334207
NSZombie 什么也没说,这段代码甚至不会在我的 iPhone 5 上崩溃,而是在我的 iPad Mini 上崩溃。方法在主线程上调用。
正如我在第一个代码块中所说的,一切都很好,我可以在我的 iPhone 和 iPad 上播放音乐。
感谢我能得到的每一个帮助。
哦,这是我的堆栈跟踪: stack trace
这背后的原因是我遵循了这个苹果指南Audio Queue Guide 播放音频,现在我想尝试通过创建一个包含所有需要信息的类来使其更加面向对象,因为Apple为此使用了一个结构。
【问题讨论】:
-
你的应用是多线程的吗?
-
是的,但是这段代码的执行应该只在主线程上执行。当我的音频开始播放时,会调用一个在后台线程上执行的回调。此回调填充缓冲区,但我的代码在任何播放发生之前已经崩溃。
-
尝试使用保护 malloc
标签: ios objective-c exc-bad-access