在做了两次相同动作后得到泄漏

时间:2010-12-27 15:31:32

标签: iphone memory-leaks

我有一个plist,我在一个nsmutabledictionary中获取它的信息。 当我第一次打电话给这个方法时,没关系。但是当我第二次这样做,第三次,等等......我得到了泄漏。代码是:

+(NSMutableDictionary *)obtainPlist{    
    if ([[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) {
        return [NSMutableDictionary dictionaryWithContentsOfFile:[self dataFilePath]];
    }
    else {
        return nil;
    }
}

我从另一个类调用此方法:

NSMutableDictionary *credenciales=[[NSMutableDictionary alloc ] initWithDictionary:[CredencialesFTP obtainPlist] ];
ajustesCredencialesTableViewController.nombre = [credenciales objectForKey:@"nombre"];
ajustesCredencialesTableViewController.password = [credenciales objectForKey:@"password"];
[credenciales release];

这是dataFilePath代码:

+(NSString *)dataFilePath{  
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:kCredenciales];
}

泄漏是在对方法obtainPlist的调用中。我尝试autorelease nsmutabledictionary但它不起作用,任何想法? 感谢。

4 个答案:

答案 0 :(得分:0)

可能是[self dataFilePath]发生了泄密,或者您可以尝试不alloc-init字典:

NSMutableDictionary *credenciales = [CredencialesFTP obtainPlist];
ajustesCredencialesTableViewController.nombre = [credenciales objectForKey:@"nombre"];
ajustesCredencialesTableViewController.password = [credenciales objectForKey:@"password"];

//编辑:所以如果在obtainPlist中发生泄漏,您可以尝试将两种方法分开,看看究竟是哪种方法造成泄漏。

首先尝试

+(NSMutableDictionary *)obtainPlist{
    [[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]];
    return nil;
}

然后

+(NSMutableDictionary *)obtainPlist{
    return [NSMutableDictionary dictionaryWithContentsOfFile:[self dataFilePath]];
}

仅用于调试和隔离问题。

答案 1 :(得分:0)

首先,什么对象泄漏?

乐器会告诉你;究竟是哪个对象泄漏,以及它分配的代码行。

一旦你有了,那么你应该在Allocations工具中打开“跟踪参考计数”并查看保留/释放的顺序。

到目前为止,您发布的代码中没有泄漏。更有可能的是,release 中有一个不是dealloc d的实例变量,您在没有release的情况下重新分配变量旧的价值。

即:

id foo = [Foo new];
foo = [Bar new]; // this leaks the Foo instance
foo = [Baz new]; // this leaks the Bar instance

当您启用引用计数记录时,保留和释放正在泄露的字典的内容是什么?

alt text

(您还可以在追踪泄漏时启用“仅跟踪有效分配”。)


啊哈!现在我们到了某个地方!

所以,泄漏的对象是NSCFString;所有意图和目的都是NSString

你有这行代码:

ajustesCredencialesTableViewController.password = [credenciales objectForKey:@"password"];

那么,你在哪里release分配给password属性的字符串?假设您的密码属性定义为retaincopy(它应该是copy),那么您需要在某处释放它。

另请注意,永远不会存储密码。永远不会。用盐哈希密码并存储密码。

答案 2 :(得分:0)

您是在模拟器中还是在实际的iOS设备上看到此泄漏?两者之间已知的不一致之处是,仪器将在模拟器上报告设备上的泄漏情况。

代码对我来说很好。

答案 3 :(得分:-2)

在这种情况下,您应该使用这种类型的函数声明:

-(NSMutableDictionary *)obtainPlist

而不是:

+(NSMutableDictionary *)obtainPlist