开发者

iPhone: Memory Leak in Custom Class and NSMutableDictionary

开发者 https://www.devze.com 2023-01-15 00:15 出处:网络
I\'ve spent a couple of days trying to find out what\'s going on. I have read loads of Memory Management documentation and I am sick to death of hearing \"for every alloc you need a release\" - I know

I've spent a couple of days trying to find out what's going on. I have read loads of Memory Management documentation and I am sick to death of hearing "for every alloc you need a release" - I know that and I still can't figure out why my code is producing memory leaks.

I am writing a simple custom class with an NSMutableDictionary as one of its properties. Basically it mimics an XMLELement. I cannot for the life of me figure out why the allocation of a dictionary is causing a memory leak. The leak occurs on the device as well as the simulator - 5 leaks on the device, and 20 on the simulator.

The leak occurs when I declare and allocate the variable *tmp.

There is also a leak when I set the attribute details (name and value).

This is driving me nuts. Please help!

Part of the code:

@interface IMXMLElement : NSObject {

NSString *strElementName;
NSString *strElementValue;
NSMutableDictionary *dictAttributes;
}

@property (nonatomic, retain) NSString *strElementName;
@property (nonatomic, retain) NSString *strElementValue;
@property (nonatomic, retain) NSMutableDictionary *dictAttributes;

@end

@implementation IMXMLElement

@synthesize strElementName;  
@synthesize strElementValue;  
@synthesize dictAttributes;

-(id)initWithName:(NSString *)pstrName
{
    self = [super init];

    if (self != nil)
    {
        self.strElementName = pstrName;
        **LEAK NSMutableDictionary *tmp = [[NSMutableDictionary alloc] in开发者_StackOverflow社区it];
        self.dictAttributes = tmp;
        [tmp release];
    }

    return self;
}

-(void)setAttributeWithName:(NSString *)pstrAttributeName  
andValue:(NSString *)pstrAttributeValue  
{  
    **LEAK [self.dictAttributes setObject:pstrAttributeValue forKey:pstrAttributeName];  
}

-(void)dealloc
{
    [strElementName release];
    [strElementValue release];
    [dictAttributes release];
    [super dealloc];    
}

The access this class using the following code:

NSString *strValue = [[NSString alloc] initWithFormat:@"Test Value"];

IMXMLElement *xmlElement = [[IMXMLElement alloc] initWithName:@"Test_Element"];
[xmlElement setAttributeWithName:@"id" andValue:strValue];


When you have strings as properties, declare them as copy, not retain.

  NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init];
  self.dictAttributes = tmp;
  [tmp release];

the above is unnecessary, instead do: (retain count will automatically be incremented for this autorelease object)

self.dictAttributes = [NSMutableDictionary dictionaryWithCapacity:0];

in dealloc do: (retain count will automatically be decremented)

self.dictAttributes = nil;

normally for properties you just set them to nil instead of explicitly releasing them since the get/setter handles that for you.


Try [dictAttributes removeAllObjects] before releasing dictAttributes.

Edit:

Also, you will positive allocation because you are allocating memory for "tmp". The memory will be retained because you now have a reference from dictAttributes.

You then have more positive allocation when you add elements to the dictionary, which also need to be allocated and are kept in memory by the dictionary's internal references


Typical syntax is NSMutableDictionary *tmp = [[[NSMutableDictionary alloc] init] autorelease];

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号