2015-03-09 3 views
0

Вот моя ситуация:Предотвращение объекта Objective-C, который вызывается из кода C++, который освобождается

Я использую Службы очереди аудио, чтобы записывать звук. Когда вызывается функция обратного вызова (как только буфер заполняется), я отправляю содержимое буфера объекту-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 «s), и после некоторых исследований я думаю, что это связано с myObj освобождения.

MyObjCObject.process выполняет цикл for из содержимого буфера, и я получаю ошибку EXC_BAD_ACCESS, даже если я просто делаю NSLog по значениям буфера.

-(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 включен для всего проекта, а остальная часть моего кода работает, как ожидалось.

Спасибо!

+0

Я не уверен, почему вы думаете, что «myObj» будет выпущен, поскольку вы не звоните «autorelease». Моя «цель c» немного ржавая, но код, который вы показываете, будет больше похож на утечку памяти. Возможно, вы могли бы показать внутренности для «MyObjCObject.process». – karmasponge

+0

@karmasponge только что добавил некоторые детали. –

+0

Вы получите 'EXC_BAD_ACCESS', если вы не используете' NSLog' правильно. –

ответ

0

Вы malloc буфер и набрасываете на '(short *)', но затем вы перечисляете буфер, используя 'bufferSize' (количество байтов). Это означало бы, что цикл «for» в конечном итоге попытается прочитать за конец буфера, потенциально вызвав «EXE_BAD_ACCESS». Это было бы потому, что каждая итерация движется вперед «коротким», а не «байтом». Вы должны изменить петлю на что-то вроде:

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

Либо это, либо изменить тип переменной-члена «буфер».

+0

Спасибо @karmasponge! Исправлена ​​проблема с EXC_BAD_ACCESS. –