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

Prevent Objective-C object called from C++ code being released

这是我的情况:

我正在使用音频队列服务来录制声音。当调用回调函数时(一旦缓冲区已满),我将缓冲区内容发送到一个 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,我的其余代码似乎按预期工作。

谢谢!

您 malloc 缓冲区并转换为“(short*)”,但随后您使用 'bufferSize'(字节数)枚举缓冲区。这意味着 'for' 循环最终会尝试读取缓冲区末尾,可能导致 'EXE_BAD_ACCESS'。那是因为每次迭代都向前移动 'short' 而不是 'byte'。您应该将循环更改为:

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

或者改变 'buffer' 成员变量的类型。