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

何が起こっているのかアイデアはありますか?

基本的に、いくつかのクラスメソッドと1つの静的ディクショナリを備えた単純なクラスが必要です。インスタンス化せずに常に使用されます。アプリの起動直後にいくつかの用途に使用したいので、メモリを解放したいと思います。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、自動解放プールを作成せずに2番目のスレッドからを呼び出さないでください。

于 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 に答える