内存泄漏过多

时间:2014-02-19 06:29:57

标签: ios objective-c memory-leaks

我遇到过以下代码中的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;

}

1 个答案:

答案 0 :(得分:0)

此示例代码似乎没有任何泄漏。但我注意到你这样做了:

AudioStreamPacketDescription *inPacketDescriptions = [self populatePacketDescriptionArray:packetDescriptionsData
                                        packetDescriptionNumber:inNumberPackets];
....
free (inPacketDescriptions);

永远不要这样做。这是一个非常糟糕的主意。

首先:方法名populatePacketDescriptionArray没有说明此方法是否分配内存。分配内存的方法应在其名称中以alloccopynew命名。这样,调用者很清楚以后需要释放内存。

第二:可能你的代码的另一部分有泄漏。如果在代码中的其他地方调用上述方法(或其他分配内存的命名方法),很容易错过对free()或dealloc的调用。