0

cocos2d バージョン 2.0 を使用してゲームをビルドしますが、ARC は使用しません。問題を見つけます: シングルトンが無効です。

私は2つのシングルトンMACROを使用していますが、問題は同じです。

#ifndef SINGLETON_INTERFACE
#define SINGLETON_INTERFACE(CLASSNAME)                  \
    +(CLASSNAME*) sharedManager;
#endif

#ifndef SINGLETON_IMPLEMENTATION
#define SINGLETON_IMPLEMENTATION(CLASSNAME)             \
                                                        \
+(CLASSNAME*) sharedManager {                           \
    static dispatch_once_t pred;                        \
    static CLASSNAME* shared##CLASSNAME = nil;          \
    dispatch_once( &pred, ^{                            \
    shared##CLASSNAME = [[self alloc] init]; });        \
    return shared##CLASSNAME;                           \
}                                                           
#endif

また

#ifndef SINGLETON_INTERFACE
#define SINGLETON_INTERFACE(CLASSNAME)              \
    +(CLASSNAME*) sharedManager;
#endif

#ifndef SINGLETON_IMPLEMENTATION            
#define SINGLETON_IMPLEMENTATION(CLASSNAME)         \
\
static CLASSNAME* shared##CLASSNAME = nil;          \
\
+(CLASSNAME*) sharedManager                         \
{                                                   \
    if (shared##CLASSNAME != nil) {                 \
        return shared##CLASSNAME;                   \
    }                                               \
\
    @synchronized(self) {                           \
        if (shared##CLASSNAME == nil) {             \
            shared##CLASSNAME = [[self alloc] init];\
        }                                           \
    }                                               \
\
    return shared##CLASSNAME;                       \
}                                                   \
\
+(id) allocWithZone:(NSZone*)zone                   \
{                                                   \
    @synchronized(self) {                           \
        if (shared##CLASSNAME == nil) {             \
            shared##CLASSNAME = [super allocWithZone:zone]; \
            return shared##CLASSNAME;               \
        }                                           \
    }                                               \
    NSAssert(NO, @ "[" #CLASSNAME " alloc] explicitly called on singleton class.");   \
    return nil;                                     \
}                                                   \
\
-(id) copyWithZone:(NSZone*)zone                    \
{                                                   \
    return self;                                    \
}                                                   \
\
-(id) retain                                        \
{                                                   \
    return self;                                    \
}                                                   \
\
-(unsigned) retainCount                             \
{                                                   \
    return UINT_MAX;                                \
}                                                   \
\
-(oneway void) release                              \
{                                                   \
}                                                   \
\
-(id) autorelease                                   \
{                                                   \
    return self;                                    \
}
#endif

使用する:

[[CCDirector sharedDirector] replaceScene:[MenuScene sharedManager]];

MenuScene が再び表示されますが、ボタン (CCMenu) またはその他の要素 (CCNode) が応答しません。つまり、最初の呼び出し、シーンはすべて問題ありません。もう一度呼び出すと、シーンは表示されますが、メニューやその他の要素は応答しません。しかし、cocos2d v1.0 では非常にうまく動作しています。

/////////////////////////////////////////////// ////////////////

次のように、「[スーパークリーンアップ]」なしで「クリーンアップ」をオーバーライドします。

-(void) dealloc
{   
    [super cleanup];
    [super dealloc];
}

-(void) cleanup 
{
    //
}

さて、シングルトンを実行しているシーンは問題ありませんが、安全ですか?

4

1 に答える 1

2

問題はおそらく、シーンの子に対して「クリーンアップ」操作を実行する CCDirector にあります。

cocos2d v2.0 では、いくつかのケースでブロックの使用が追加されました。これは、シングルトンがメモリ内に留まるかどうかに関係なく発生する「クリーンアップ」中に解放されます。

v2.0 移行ガイドから:

クリーンアップ フラグを YES に設定すると、解放されたリソースを暗黙的に参照しているアプリケーションのロジックに副作用が生じる可能性があります。内部でブロックを使用してアクションを起動する CCMenuItems は、問題を引き起こし、アクションを起動しない可能性があります。これは、クリーンアップ フラグをアクティブにしてアイテムを親ノードから削除し、再度追加したと仮定すると、明確な兆候の 1 つです。フラグを NO に変更するだけで十分です。

移行ガイド: http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:migrate_to_v2.0#ccsprite


率直に、次のいずれかをお勧めします。

  • シングルトンの子に対して「クリーンアップ」が呼び出されるのを安全に防ぐ方法を見つけてください。
  • または: シーン メカニズムを使用する代わりに、表示/非表示にする CCLayer の子としてすべてをメモリに保持します。
  • または: シングルトンを使用せず、毎回シーンを再作成します。
于 2012-06-05T15:34:18.223 に答える