2010-12-05 55 views
0

我是新来的发展并不能想出解决办法:为什么不是这个代码泄漏?

for(NSString *collectionName in jsonObjects) 
    { 
    NSDictionary *collection = [[NSDictionary alloc] init]; 
    collection = [jsonObjects valueForKey:collectionName]; 
    NSArray *items = [[NSArray alloc] initWithArray:[collection valueForKey:@"items"]]; 
    NSNumber *lastAccess = [[NSNumber alloc] init]; 

    lastAccess = [collection valueForKey:@"lastAccess"]; 

    [items release]; 
    } 

我不明白为什么要这样,当我DO版本要么LASTACCESS收集,程序崩溃与EXC_BAD_ACCESS错误...,但如果我不发布项目我得到一个泄漏。任何人都可以请澄清这一点。我认为如果你使用了alloc,那么你拥有这个参考,因此必须发布?

回答

1
for(NSString *collectionName in jsonObjects) 
{ 
    NSDictionary *collection = [[NSDictionary alloc] init]; // Allocation 
    collection = [jsonObjects valueForKey:collectionName]; // overwriting above, LEAKS 
    NSArray *items = [[NSArray alloc] initWithArray:[collection valueForKey:@"items"]]; // Allocation 
    NSNumber *lastAccess = [[NSNumber alloc] init]; // Allocation 
    lastAccess = [collection valueForKey:@"lastAccess"]; // overwriting above, LEAKs 
    [items release]; 
} 

电话“新”返回引用到被“自动释放”,这意味着他们不属于你,释放它们会导致崩溃的对象。你可以使用它们,但只能在你所在功能的范围内,如果你需要它们以后使用,你需要在它们上面调用retain。因此,在调用存取函数时,只需声明所需的变量而不创建新的对象。

alloc创建一个新的对象,在collection要创建一个空的NSDictionary的情况下,但你及时覆盖与自动释放参考你valueForKey:该得到的将创建一个泄漏引用新对象。由于最初创建的对象不会被释放。

大概应该是这样的

for(NSString *collectionName in jsonObjects) 
{ 
    NSDictionary *collection = [jsonObjects valueForKey:collectionName]; 
    NSArray *items = [collection valueForKey:@"items"]; 
    NSNumber *lastAccess = [collection valueForKey:@"lastAccess"]; 
} 

我认识到,与具有这样一个愿意人群阅读的手册回答问题的能力已经变成了一个苦差事,但如果你想进步,你应该有一个看,大部分的苹果文档写得非常好,因为这些东西都去了。 memory management guide将解决很多问题。

+0

谢谢Harald,我看了内存管理指南,但误解我猜:(我尽管你知道你在说什么改写我的初始alloc/init,但是我确实有一个关于NSDictionary * collection = [jsonObjects valueForKey:collectionName];和NSDictionary * collection = [NSDictionary dictionaryWithDictionary:[jsonObjects valueForKey :collectionName]];即这两个声明在功能上是否相同,文档没有说清楚? – Beliskna 2010-12-05 18:32:48

0

在该代码中,您只是重新指定lastAccess指针,这会使alloc版本NSNumber泄漏。您需要实际设置lastAccess指向的NSNumber对象的值。

编辑:

我已经把一些示例代码,但我把它出来,因为我现在认识到,上面的代码示例中有太多的问题。看看NSDictionary的文档。用collection,你正在创建一个对象,然后通过重新指定其他指针来泄漏它。一旦你解决了这些问题,我建议用新代码更新问题。

4

该代码存在一堆问题。暂时忽略基金会缓存某些常用值。

这种模式是没有意义:

NSDictionary *collection = [[NSDictionary alloc] init]; 
collection = [jsonObjects valueForKey:collectionName]; 

第一行创建的NSDictionary的(空)的实例与所述第二线及时覆盖引用。无论是泄漏还是完全没有意义;第一行不需要分配/分配。稍后,lastAccess也一样。

由于第二行是返回一个非拥有的引用,试图release它会导致崩溃。

请注意如果出现死机,将会出现回溯。这个问题很直接,不需要,但总是寻找线索的回溯。

请注意,您实际上不会看到NSNumberNSDictionary实例的泄漏,因为基金会恰好具有这些实例的单例。在NSNumber情况下,它没有任何意义。空字典,但是,经常使用,并有一个单例节省内存。上述

+0

感谢您回到我的皮包,我不太清楚单身是什么,但我会检查出文档:) – Beliskna 2010-12-05 18:26:22

0

继@bbum,我会写你这样的代码:

for(NSString *collectionName in jsonObjects) 
{ 
NSDictionary *collection = [jsonObjects valueForKey:collectionName]; 
NSArray *items = [NSArray arrayWithObject:[collection valueForKey:@"items"]]; 
NSNumber * lastAccess = [collection valueForKey:@"lastAccess"]; 
} 

在这种情况下,所有变量将自动释放,所以你不需要做手动释放他们。不包含“的alloc”或