Search code examples
objective-cmemory-leaksios4

iOS memory leak by dictionary


I am new to iOS programming and I have developed an application for my client. When I run the application using Instruments, however, there appears to be a memory leak problem caused by a dictionary, but if I release it, then the app crashes. I am not sure what the problem is.

This is image of Instruments: http://www.flickr.com/photos/71234685@N02/6791493522/in/photostream/

-(void) generateLiquidProductData:(NSArray*) liquidProduct {

    int _count = 52;

    self.liquidProductData = [[NSMutableArray alloc] initWithCapacity:_count];

    for (int i = 0; i < _count; i++){

        float x = i;
        float y;

        if ((liquidProduct != (id)[NSNull null]) && (liquidProduct != nil) && ([liquidProduct count] != 0)) {

            y = [[liquidProduct objectAtIndex:i] floatValue];
            y = round(y * 10000.0f) / 10000.0f;
        }
        else {

            y = 0.0;
            y = round(y * 10000.0f) / 10000.0f;
        }

        NSDictionary* _gotLiquidProduct = [NSDictionary dictionaryWithObjectsAndKeys:
                                                 [NSNumber numberWithDouble:x],X_VAL,
                                                 [NSNumber numberWithDouble:y],Y_VAL,
                                                 nil];
        NSLog(@"This is y %.5f", y);
        [self.liquidProductData addObject:_gotLiquidProduct];
    }
}

Solution

  • The memory leak is due to this line:

    self.liquidProductData = [[NSMutableArray alloc] initWithCapacity:_count];
    

    Most likely, the property is either marked as retain or copy (usually the former). The correct way to use it would be:

    self.liquidProductData = [NSMutableArray arrayWithCapacity:_count];
    

    The leak is because alloc returns an owning reference that you later need to release, but you do not release it. You now assign it to the property which retains the instance. The "relative retain count" is now +2. If you assign a new value to this property, the old instance will get released, but this only makes the "relative retain count" drop to +1, thus the instance never gets deallocated. This in turn will also leak your dictionary and its values, since they are still retained by the leaked array.