【发布时间】:2011-08-23 15:01:57
【问题描述】:
所以我觉得这是一个很难正确提出的问题,但这是我最好的选择。
我正在用 obj-c 编写一个 iPhone 应用程序,但它涉及声音合成,而我在核心音频中的教程使用了我认为是 C(或者可能是 C++)编程的声音合成,我问了一个我认识的人使用C++,他不认识它,但教程告诉我将文件名更改为 .mm 用于 C++)。出现的问题是我有巨大的内存泄漏,很可能是因为我不知道如何正确调用事物。
当使用这部分代码时,我会收到大量错误,如下所示: 2011-08-23 10:18:08.769 myProgram[451:5e03] * __NSAutoreleaseNoPool(): _NSCallStackArray 类的对象 0x171e90 自动释放,没有适当的池 - 只是泄漏
使用仪器,我找到了泄漏发生的位置,并在其中发表了评论。
这是所有泄漏出现的函数:
static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
// Get a reference to the object that was passed with the callback
// In this case, the AudioController passed itself so
// that you can access its data.
AudioController *THIS = (AudioController*)inRefCon;
// Get a pointer to the dataBuffer of the AudioBufferList
AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData;
// Calculations to produce a 600 Hz sinewave
// A constant frequency value, you can pass in a reference vary this.
float sinSignal;
for (UInt32 i = 0; i < inNumberFrames; ++i) {
outA[i] = 0;
}
THIS->theBall = [[THIS->navDelegate ballsG] objectAtIndex:0];
THIS->amtPlaying = [[THIS->theBall playingLines] count];
//NSLog(@"%i", THIS->amtPlaying);
for (int i = 0; i < THIS->amtPlaying; i++)
{
// Loop through the callback buffer, generating samples
for (UInt32 i = 0; i < inNumberFrames; ++i) {
// calculate the next sample
sinSignal = sin( [[[THIS->theBall playingLines] objectAtIndex:i] theta] ); //leak here
sinSignal *= [[[THIS->theBall playingLines] objectAtIndex:i] volume] ;
sinSignal /= THIS->amtPlaying;
// Put the sample into the buffer
// Scale the -1 to 1 values float to
// -32767 to 32767 and then cast to an integer
outA[i] += (SInt16)(sinSignal * 32767.0f);
// calculate the phase for the next sample
[[[THIS->theBall playingLines] objectAtIndex:i] increaseTheta: [[[THIS->theBall playingLines] objectAtIndex:i] incrementer]];
}
}
return noErr;
}
如果我可以提供更多信息来帮助您理解我的问题,请在评论中告诉我。谢谢!
【问题讨论】:
-
如果您尝试在后台进行处理,您需要在函数的开头添加
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init],然后在末尾添加[pool drain],因为您正在使用可能的自动释放对象。 (ballsG,objectAtIndex:,playingLines) -
消除了其他泄漏,现在仪器显示我正在泄漏 NSAutoReleasePool。
-
你在
return noErr;之前添加了[pool drain]?此外,无论您在启动新线程时调用哪种方法,NSAutoreleasePool都应该是在那里创建的第一件事,然后做的最后一件事应该是在同一方法中调用drain。 -
是的,[pool drain] 语句就在 return no Err 之前;并且 NSAutoreleasePool 在方法中首先被调用。
标签: objective-c c ios xcode core-audio