【问题标题】:Prevent Objective-C object called from C++ code being released防止从 C++ 代码调用的 Objective-C 对象被释放
【发布时间】:2015-03-09 23:44:21
【问题描述】:

这是我的情况:

我正在使用音频队列服务来录制声音。当回调函数被调用时(一旦缓冲区已满),我将缓冲区内容发送到一个 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 的 process 方法),经过一些研究我猜它与 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 已在整个项目中启用,我的其余代码似乎按预期工作。

谢谢!

【问题讨论】:

  • 我不确定您为什么认为“myObj”会被释放,因为您没有调用“autorelease”。我的“目标 c”有点生疏,但您显示的代码更像是内存泄漏。也许您可以展示“MyObjCObject.process”的内部结构。
  • @karmasponge 刚刚添加了一些细节。
  • 如果你没有正确使用NSLog,你会得到EXC_BAD_ACCESS
  • 我们需要知道 MyObjCObject process: 的内部结构 现在,据我所知,这一行 qr-&gt;objectiveC_Call([NSData dataWithBytes:inBuffer-&gt;mAudioData length:inBuffer-&gt;mAudioDataBytesCapacity]); 正在创建一个 autoreleased NSData 对象,该对象将在当前运行循环后释放除非您特别将其保留在某处。

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


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢@karmasponge! EXC_BAD_ACCESS 问题已修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
相关资源
最近更新 更多