iPhone:自定义类和NSMutableDictionary中的内存泄漏

时间:2010-09-02 02:31:45

标签: iphone memory-leaks nsmutabledictionary

我花了几天时间试图找出发生了什么。我已阅读大量的内存管理文档,我厌倦了听到“对于每个需要释放的分配器” - 我知道这一点,我仍然无法弄清楚为什么我的代码会产生内存泄漏。

我正在编写一个简单的自定义类,其中包含NSMutableDictionary作为其属性之一。基本上它模仿XMLELement。我不能为我的生活弄清楚为什么字典的分配导致内存泄漏。泄漏发生在设备和模拟器上 - 设备上有5个泄漏,模拟器上有20个泄漏。

当我声明并分配变量* tmp时发生泄漏 设置属性详细信息(名称和值)时也存在泄漏。

这让我疯了。请帮忙!

部分代码:

@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] init];
        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];    
}

@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] init]; 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]; }

使用以下代码访问此类:

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

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

3 个答案:

答案 0 :(得分:0)

在发布dictAttributes之前尝试[dictAttributes removeAllObjects]。

编辑:

此外,您将积极分配,因为您正在为“tmp”分配内存。内存将被保留,因为您现在有来自dictAttributes的引用。

当您向字典添加元素时,您可以获得更多正面分配,这些元素也需要分配并通过字典的内部引用保存在内存中

答案 1 :(得分:0)

典型语法为NSMutableDictionary *tmp = [[[NSMutableDictionary alloc] init] autorelease];

答案 2 :(得分:0)

当您将字符串作为属性时,将它们声明为副本,而不是保留。

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

以上是不必要的,而是: (对于此自动释放对象,保留计数将自动递增)

self.dictAttributes = [NSMutableDictionary dictionaryWithCapacity:0];

在dealloc中: (保留计数将自动减少)

self.dictAttributes = nil;

通常对于属性,您只需将它们设置为nil而不是显式释放它们 因为get / setter会为你处理。