1

プロジェクトの静的データを保持する単純なシングルトン クラスを作成しました。このシングルトンに初めてアクセスするのは、Cocos2d シーンの onEnter メソッドです。ただし、後で別の方法 (同じシーン) で再度アクセスしようとすると、このシングルトンは既に解放されています。混乱しています。シングルトンの割り当てが解除されないようにするにはどうすればよいですか?

これが私のシングルトンのインターフェース部分です:

#import <Foundation/Foundation.h>

@interface OrchestraData : NSObject
+(OrchestraData *)sharedOrchestraData;
@property (retain, readonly) NSArray *animalNames;
@end

実装:

#import "OrchestraData.h"

@implementation OrchestraData
@synthesize animalNames = animalNames_;

+(OrchestraData*)sharedOrchestraData
{
    static dispatch_once_t pred;
    static OrchestraData *_sharedOrchestraData = nil;

    dispatch_once(&pred, ^{ _sharedOrchestraData = [[OrchestraData alloc] init]; });
    return _sharedOrchestraData;
}

-(id)init {
    if (self = [super init]) {
        animalNames_ = [NSArray arrayWithObjects:@"giraffe", @"giraffe", @"giraffe", @"giraffe", nil];
    }
    return self;
}
@end

私はこのようにシングルトンを使用しています:

[[OrchestraData sharedOrchestraData] animalNames];

更新: NSZombies を有効にして再調査しましたが、シングルトン自体ではなく、NSArrays がリリースされたように見えます。私は何をしますか?

4

4 に答える 4

4

この方法でシングルトンを実装する必要があります。

1) シングルトン クラスの .h ファイル内:

+ (SingletonClass *)instance;

2) .m ファイル内:

+ (SingletonClass *)instance {

    static SingletonClass* instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
        //your init code here
    });
    return instance;
}

シングルトンを呼び出したい場合は、 を呼び出すだけ[SingletonClass instance]です。

「dispatch_once_t」に興味がある場合は、Grand Central Dispatch についてお読みください: http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

于 2012-10-09T15:47:30.673 に答える
2

RE アップデート:

NSArrayautorelease イニシャライザを使用していて、それを ivar に直接割り当てているため、割り当てが解除されarrayWithObjectsますanimalNames_。したがって、保持されません。

これを修正するには、配列をプロパティに割り当てます。

self.animalNames = [NSArray arrayWithObjects:@"giraffe", @"giraffe", @"giraffe", @"giraffe", nil];

ところで、ARC の下では、ivar が強力な (保持する) 参照であったため、これは問題になりませんでした。誰かに ARC への切り替えを勧めるのに飽きることはありません。これは 1 年以上前から利用可能であり、MRC コードを使用する意味はまったくありません。開発者がまだ、より簡単で、より速く、簡単なオプションを使用していないのを見ると、本当に心が痛みます。(暴言) :)

于 2012-10-09T19:12:34.490 に答える
-2

必要な場所にポインターをセットアップします。

-(void)someMethod {

MySingleton *singleton = [MySingleton sharedSingleton];
singleton.data = YES; //dumb example to show you did something...

}

-(void)someOtherMethod {

MySingleton *singleton = [MySingleton sharedSingleton]; //You have to create a new pointer...
singleton.data = NO; //another dumber example to show you did something...

}

注:これは、私と同じ方法でシングルトンを作成したことを前提としています...コードが異なる可能性があるため、私の答えが適用されない可能性があります...

于 2012-10-09T15:39:06.920 に答える
-3

以下のメソッドをシングルトン クラス内で上書きする必要があります。プログラムで誰かが初期化し[[SingletonClass alloc] init]た場合、シングルトンは別のインスタンスを持ち、それを解放するとエラーが発生するためです。

+ (id)allocWithZone:(NSZone *)zone{
    return [[self SingletonClass] retain];  
}

- (id)copyWithZone:(NSZone *)zone{
    return self;
}

- (id)retain{
    return self;
}
于 2012-10-09T16:03:03.527 に答える