我遇到过以下代码中的NSInlineData内存泄漏(特别是底部的while循环)。我已经用尽了大多数内存管理方法,但似乎无法解决这个问题。下面的代码是音乐流应用程序的一部分。
-(void)readRingBufferDataBit
{
if (state == AS_STOPPED || forcedStop == YES)
{
if(ringBufferReaderTimer) {
[ringBufferReaderTimer invalidate];
ringBufferReaderTimer = nil;
NSLog(@"The timer has been invalidated");
}
[[NSNotificationCenter defaultCenter] postNotificationName:playbackStoppedNotification object:self];
return;
}
void *readPointer;
allBytesAvailable = [ringBuffer lengthAvailableToReadReturningPointer:&readPointer];
[self printState:state];
if (allBytesAvailable == 0) {
gEmptyRingBufferCount++;
if ((gEmptyRingBufferCount) >= 20 || ((stopReason == AS_INITIALIZED) && (PacketTypeEndOfSong) && gEmptyRingBufferCount >= 2)) {
[[NSNotificationCenter defaultCenter] postNotificationName:playbackFinishedNotification object:self];
state = AS_STOPPED;
stopReason = AS_STOPPING_EOF;
}
return;
}
NSData *ringBufferReadData = [NSData dataWithBytes:readPointer length:allBytesAvailable];
[ringBuffer didReadLength:allBytesAvailable];
UInt32 ringBufferReadDataOffset = 0;
while (ringBufferReadDataOffset < allBytesAvailable) {
int packetBytesFilled = [[ringBufferReadData subdataWithRange:NSMakeRange(12 + ringBufferReadDataOffset, 4)] pm_int32AtOffset:0];
int packetDescriptionsBytesFilled = [[ringBufferReadData subdataWithRange:NSMakeRange(16 + ringBufferReadDataOffset, 4)] pm_int32AtOffset:0];
int offset = AUDIO_BUFFER_PACKET_HEADER_SIZE + ringBufferReadDataOffset;
NSData *audioBufferData = [NSData dataWithBytesNoCopy:(char *)([ringBufferReadData bytes] + offset) length:packetBytesFilled freeWhenDone:NO];
offset += packetBytesFilled;
NSData *packetDescriptionsData = [NSData dataWithBytesNoCopy:([ringBufferReadData bytes] + offset) length:packetDescriptionsBytesFilled freeWhenDone:NO];
UInt32 inNumberPackets = packetDescriptionsBytesFilled/AUDIO_STREAM_PACK_DESC_SIZE;
AudioStreamPacketDescription *inPacketDescriptions = [self populatePacketDescriptionArray:packetDescriptionsData
packetDescriptionNumber:inNumberPackets];
[self handleAudioPackets:[audioBufferData bytes]
numberBytes:packetBytesFilled
numberPackets:inNumberPackets
packetDescriptions:inPacketDescriptions];
ringBufferReadDataOffset += AUDIO_BUFFER_PACKET_HEADER_SIZE + packetBytesFilled + packetDescriptionsBytesFilled;
free (inPacketDescriptions);
packetDescriptionsData = NULL;
audioBufferData = NULL;
}
ringBufferReadData = NULL;
}
答案 0 :(得分:0)
此示例代码似乎没有任何泄漏。但我注意到你这样做了:
AudioStreamPacketDescription *inPacketDescriptions = [self populatePacketDescriptionArray:packetDescriptionsData
packetDescriptionNumber:inNumberPackets];
....
free (inPacketDescriptions);
永远不要这样做。这是一个非常糟糕的主意。
首先:方法名populatePacketDescriptionArray
没有说明此方法是否分配内存。分配内存的方法应在其名称中以alloc
,copy
或new
命名。这样,调用者很清楚以后需要释放内存。
第二:可能你的代码的另一部分有泄漏。如果在代码中的其他地方调用上述方法(或其他分配内存的命名方法),很容易错过对free()或dealloc的调用。