【问题标题】:NSDictionary as propertyNSDictionary 作为属性
【发布时间】:2011-04-21 05:17:00
【问题描述】:

通过使用以下代码,我发现内存泄漏指向“NSDictionary *dw = [NSDictionary dictionaryWithContentsOfFile:path];”行

NSDictionary    *_allData;

@property (nonatomic, retain) NSDictionary  *allData;

@synthesize allData = _allData;

+ (NSString*)getNSPath

{
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

 NSString *documentsDirectory = [paths objectAtIndex:0];

 NSString *path = [documentsDirectory stringByAppendingPathComponent:@"alarm.plist"];

 return path;
}


- (NSDictionary *)allData
{
 NSString *path = [saveAlarm getNSPath];
 NSDictionary *dw = [NSDictionary dictionaryWithContentsOfFile:path];


 _allData = [NSDictionary dictionaryWithDictionary:dw];

    return _allData;
}

pList 中的数据正在发生变化,当我要求通过属性检索那里的新内容时,它就会泄漏。 任何建议如何明确?或者如何实现这种东西而不泄漏?

谢谢

【问题讨论】:

    标签: iphone memory-leaks nsdictionary


    【解决方案1】:

    您需要在重新分配之前释放 _allData。您还需要在分配时保留它。

    编辑:结合 Robert 的改进以摆脱不需要的 NSDictionary。

    EDIT2:因为您要跨 API 边界返回对象,所以需要将其重新调整为自动释放的对象。

    - (NSDictionary *)allData
    {
         NSString *path = [saveAlarm getNSPath];
         [_allData release];
         _allData = [[NSDictionary dictionaryWithContentsOfFile:path] retain];
    
        return [_allData autorelease];
    }
    

    您发布的代码有点奇怪,因为您正在创建一个名为 allData 的属性,告诉它使用 _allData 作为 ivar(使用 @synthesize),然后实现设置 ivar 的自定义 getter。如果将属性声明为只读,则可以删除 @synthesize 语句。

    如果你只在这个方法中使用 _allData 而不是在这个类的任何其他地方,你可以完全摆脱它。这是一个更简单的版本,它做同样的事情:

    - (NSDictionary *)allData
    {
         NSString *path = [saveAlarm getNSPath];
         return [NSDictionary dictionaryWithContentsOfFile:path];
    }
    

    【讨论】:

    • 此解决方案使添加保留的行的内存泄漏 864 字节。不知道当它是类方法时为什么要保留它。
    • 啊。当您跨 API 边界返回对象时,您需要将其作为自动释放返回。我会更新代码。
    • 您需要保留它,因为您将它存储在 ivar 中。否则,对象将在您的 ivar 仍有引用时被释放。
    • 同样重要的是要注意 Instruments 显示的是泄漏内存的分配位置,而不是泄漏发生的位置。您需要查看对象上的所有保留和释放调用,并找到额外的保留或丢失的释放。
    • 将此解决方案 + 更改属性为只读且无泄漏。谢谢
    【解决方案2】:

    你为什么不替换

    NSDictionary *dw = [NSDictionary dictionaryWithContentsOfFile:path];
    
    
    _allData = [NSDictionary dictionaryWithDictionary:dw];
    

    _allData = [NSDictionary dictionaryWithContentsOfFile:path];
    

    那么您不必担心 dw NSDictionary 的 autorelease 可能会导致您的泄漏。

    【讨论】:

    • 这是一个很好的建议,因为它的代码要少得多,而且您不需要创建额外的字典,但这仍然会泄漏。泄漏是因为您在没有首先释放现有值的情况下将新的 NSDictionary 分配给 _allData。
    • 此解决方案在开始时不会泄漏,但当我要求检索新值时会发生位泄漏(32 字节)......所以到目前为止没有进展
    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多