2

这是一个简单的类:

#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

3 回答 3

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不创建自动释放池的情况下从第二个线程调用您。

于 2012-04-20T18:49:33.187 回答
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];
      ...
于 2012-04-20T19:02:26.357 回答
-1

您在做什么是将字典放在堆栈上(坦率地说,这很愚蠢,因为您有很多方法可以做到这一点)并且它会泄漏,因为它永远不会从堆栈中释放。

创建 NSDictionary 是为了与自动释放池一起使用(是的..我知道在某些情况下使用静态的更好,但这些情况非常罕见)

在界面中声明NSMutableDictionary *elementToClassMapping;,一切都会正常工作

于 2012-04-20T19:13:24.277 回答