2012-04-20 56 views
2

这里有一个简单的类:静态的NSMutableDictionary “只是泄漏”

#import "One.h" 
#import "Two.h" 

@implementation DataFileRegistrar 

static NSMutableDictionary *elementToClassMapping; 

+ (void)load 
{ 
    [self registerClass:[One class] forElement:@"one"]; 
    [self registerClass:[Two class] forElement:@"two"]; 
} 

+ (void)registerClass:(Class)class forElement:(NSString *)element 
{ 
    if (!elementToClassMapping) { 
     elementToClassMapping = [NSMutableDictionary dictionaryWithObject:class forKey:element]; 
    } else { 
     [elementToClassMapping setValue:class forKey:element]; 
    } 
} 

+ (id)classForElement:(NSString *)element 
{ 
    return [elementToClassMapping valueForKey:element]; 
} 

@end 

问题是这样的编译器消息:

objc[7172]: Object 0x6840720 of class __NSCFDictionary autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

任何想法是怎么回事?

基本上,我想要一个简单的类,有几个类方法和一个静态字典。它总是在没有实例化的情况下使用。我想在应用程序启动后立即使用它,然后我想释放它的内存。我认为ARC可以照顾这一点。

回答

4

您的班级'+load正在调用autorelease的调用方法。

您的课程在main之前加载。

您可以明确地在+load创建一个自动释放池:

+ (void)load 
{ 
    @autoreleasepool { 
     [self registerClass:[One class] forElement:@"one"]; 
     [self registerClass:[Two class] forElement:@"two"]; 
    } 
} 

然而,它往往是更好地main创建任何线程之前,确保你的程序的初始化顺序,并明确载入:

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     [DataFileRegistrar initializeStaticStuff]; 
     ... 
+0

工程就像一个魅力!非常感谢! – 2012-04-20 20:00:45

+0

@RudolfAdamkovic不客气 – justin 2012-04-20 20:18:59

5

你不应该在静态变量上使用自动释放对象。

更改行...

elementToClassMapping = [NSMutableDictionary dictionaryWithObject:class forKey:element]; 

elementToClassMapping = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObject:class] forKeys:[NSArray arrayWithObject:element]]; 

而且也不叫从第二个线程你+ (void)registerClass:(Class)class forElement:(NSString *)element而无需创建一个自动释放池。

+0

自动释放的对象是好的;但未保留的autorelease对象不是。 :)你仍然可以使用'dictionaryWithObject:forKey :;;它只是需要保留。 – bbum 2012-04-20 20:00:58

+0

你的权利。但是当我想避免autorelease我做对了:)。这对于稍后阅读更好的代码来说更重要。 – 2012-04-20 20:16:27

+0

顺便说一句:你建议重写使用两个自动发布的对象[NSArray实例] .... – bbum 2012-04-20 20:21:00

-1

你在干什么,把字典放在堆栈上(这是坦率的愚蠢的,因为你有太多的方法不这样做),它泄漏,因为它永远不会从叠加。创建

的NSDictionary与自动释放池被使用(yes..i知道有一些情况下,最好使用静态的,但这些案件是非常非常罕见的)

接口和一切宣布NSMutableDictionary *elementToClassMapping;将工作得很好

+0

这与堆栈无关。分析不正确,建议的修复不正确。 – bbum 2012-04-20 19:59:34