我有一个代码,我们多次使用我们的应用程序,它是一个获取缓冲区样本并处理它的类,然后将通知发送回主类。 代码是c和objective-c。
它工作得很好,但是我可以在instruments-allocation工具中看到内存增长。 "整体字节"以每秒100k的速度不断增长。因为我知道他们是谁的代码的某些部分。
这是回调函数,带有产生问题的行。
它每秒都会发生很多次。
我也不太明白在哪里放*pool
:
static OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
AudioBuffer buffer;
buffer.mNumberChannels = 1;
buffer.mDataByteSize = inNumberFrames * 2;
//NSLog(@"%ld",inNumberFrames);
buffer.mData = malloc( inNumberFrames * 2 );
// Put buffer in a AudioBufferList
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0] = buffer;
// block A
OSStatus status;
status = AudioUnitRender(audioUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
&bufferList);
//end block A
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int16_t *q = (int16_t *)(&bufferList)->mBuffers[0].mData;
int16_t average ;
for(int i=0; i < inNumberFrames; i++)
{
average=q[i];
if(average>100) // lineB
reducer++;
//blockC
if(reducer==150 )
{
average= preSignal + alpha*(average-preSignal);
//NSLog(@"average:%d",average);
//call scene
[dict setObject:[NSNumber numberWithInt:average] forKey:@"amp" ] ;
[[NSNotificationCenter defaultCenter] postNotificationName:@"DigitalArrived" object:nil userInfo:dict];
reducer=0;
preSignal=average;
}
//end blockC
}
free(buffer.mData);
[pool release];
return noErr;
}
行: 忽略blockC一秒钟。 删除blockA和lineB解决所有问题。 只删除其中一个 - 泄漏。
我无法理解这里的成长。
答案 0 :(得分:0)
只是一个猜测,但在录制回调函数(这是一个超级时间关键函数)中分配一个新的NSAutoreleasePool可能是一个坏主意。
实际上,你为什么要这样做呢?你不应该在main.m中为整个应用程序安装一个游戏池吗?这可能会导致你的一些泄密。
答案 1 :(得分:0)
您不应该在音频单元渲染回调中执行任何需要内存分配的操作。对于使用通用Objective C,实时要求太紧。
由于您不应在音频单元回调中分配池或任何其他内存,因此不应使用可能或实际创建任何对象的任何Objective C方法,例如字典修改或通知创建。您可能必须回退到在渲染回调中使用普通C(设置标志),并在另一个线程中的渲染回调之外执行Objective C消息传递(例如,在轮询定时器回调中的标志之后)。