防止从C ++代码中释放的Objective-C对象被释放

时间:2015-03-09 23:44:22

标签: c++ ios exc-bad-access audioqueueservices

以下是我的情况:

我正在使用音频队列服务来录制声音。当调用回调函数时(缓冲区满了),我将缓冲区内容发送到objective-C对象进行处理。

void AQRecorder::MyInputBufferHandler(void *                                inUserData,
                                      AudioQueueRef                         inAQ,
                                      AudioQueueBufferRef                   inBuffer,
                                      const AudioTimeStamp *                inStartTime,
                                      UInt32                                inNumPackets,
                                      const AudioStreamPacketDescription*   inPacketDesc)
{
    AQRecorder *aqr = (AQRecorder *)inUserData;
    try {
        if (inNumPackets > 0) {
            NSLog(@"Callback ! Sending buffer content ...");
            aqr->objectiveC_Call([NSData dataWithBytes:inBuffer->mAudioData length:inBuffer->mAudioDataBytesCapacity]);
            aqr->mRecordPacket += inNumPackets;
        }

        if (aqr->IsRunning())
            XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
    } catch (CAXException e) {
        char buf[256];
        fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
    }
}

void AQRecorder::objectiveC_Call(NSData *buffer) {
    MyObjCObject *myObj = [[MyObjCObject alloc] init];
    [myObj process:buffer];
}

这里的问题是我在进程中得到了一个EXC_BAD_ACCESS(来自 myObj 的进程方法),经过一些研究后我猜它与 myObj 有关释放。

MyObjCObject.process从缓冲区内容执行for循环,即使我只对缓冲区值执行NSLog,也会收到EXC_BAD_ACCESS错误。

-(void)run:(NSData *)bufferReceived {
   NSUInteger bufferSize = [bufferReceived length];
   self.buffer = (short *)malloc(bufferSize);
   memcpy(self.buffer, [bufferReceived bytes], bufferSize);

   for(int i= 0; i < bufferSize; i++) {
      NSLog("value: %i", buffer[i]);
   }

}  

你能告诉我这样做的方法吗?

ps:我的文件有 .mm 扩展名,整个项目启用了ARC,其余代码似乎按预期工作。

谢谢!

1 个答案:

答案 0 :(得分:0)

你将缓冲区malloc并转换为&#39;(短*)&#39;但是然后你使用&#39; bufferSize&#39;来枚举缓冲区。 (字节数)。这意味着&#39; for&#39;循环最终会尝试读取超过缓冲区的末尾,可能导致“EXE_BAD_ACCESS”。那将是因为每次迭代都是由一个“短暂的”&#39;而不是一个&#39;字节&#39;。您应该将循环更改为:

for(int i= 0; i < bufferSize / sizeof(short); i++) {
    NSLog("value: %i", buffer[i]);
}

或者改变&#39;缓冲区的类型&#39;成员变量。