当我不使用局部变量时,为什么会出现 EXC BAD ACCESS?

Why am I getting EXC BAD ACCESS when I don't use a local variable?

我有这段代码可以将数据从 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 是一个 class,其中包含一个 属性 的 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 时崩溃,对于 i=0 OSStatus 报告错误,代码如下:2003334207

NSZombie 什么也没说,这段代码甚至不会在我的 IPhone 5 上崩溃,而是在我的 iPad Mini 上崩溃。方法在主线程上调用。

正如我在第一段代码中所说的那样,一切都很好,我可以在 iPhone 和 iPad 上播放音乐。

我很感激能得到的每一个帮助。

哦,这是我的堆栈跟踪: stack trace

这背后的原因是我遵循了这个 Apple 指南 Audio Queue Guide 播放音频,现在我想尝试通过创建一个 class 使其更加面向对象,其中包含所有需要的信息,因为 Apple 为此使用了一个结构。

我刚刚通过更改此行修复了它

- (void)handle:(void *)aqData audioQueue:(AudioQueueRef) audioQueue buffer:(AudioQueueBufferRef) buffer

至此

- (void)handle:(TestViewController *)aqData audioQueue:(AudioQueueRef) audioQueue buffer:(AudioQueueBufferRef) buffer
{
    UInt32 numBytesReadFromFile;
    UInt32 numPackets = vc.file.numberOfPacketsToRead;

    AudioFileReadPacketData(vc.file.audioFile, NO, &numBytesReadFromFile, vc.packetDescs, vc.file.currentPacket, &numPackets, buffer->mAudioData);