2

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

我正在编写一个简单的自定义类,其中 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];    
}

使用以下代码访问此类:

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

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

4

3 回答 3

0

在释放 dictAttributes 之前尝试 [dictAttributes removeAllObjects]。

编辑:

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

然后,当您将元素添加到字典时,您将获得更多的正分配,这些元素也需要分配并由字典的内部引用保存在内存中

于 2010-09-02T02:55:50.290 回答
0

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

于 2010-09-02T03:08:03.953 回答
0

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

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

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

self.dictAttributes = [NSMutableDictionary dictionaryWithCapacity:0];

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

self.dictAttributes = nil;

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

于 2010-09-02T03:31:24.343 回答