4

Cocos2d-iphone から移植したゲームに Cocos2d-x を使用しています。元のプログラマーは、Objective-C の「機能」を使用して、多くのずさんなことを行う方法として、nil オブジェクトの呼び出しでクラッシュしないようにしているようです。

これが関連している場合はわかりませんが、私のコードでは release() を手動で呼び出すことはなく、削除なども行いません。私は ->removeObject() をまったく呼び出しません (ただし、私が持っているのと同じ問題にはなりません)。

ここでの問題: ゲームが実行されているとき、ランダムな瞬間に (ランダムではありませんが、明らかにそのように見えます)、子ノードが NULL に設定されます。これは私のコードだけでなく、Cocos2d の内部にも影響を与えます。例:

    CCLog("----------------");
    for(int j = 0; j < this->getChildren()->count(); j++)
    {
        CCObject *child = this->getChildren()->objectAtIndex(j);
        EnemySprite *enemy = dynamic_cast<EnemySprite*>(child);
        if (enemy != NULL) {
            CCLog("Enemy with tag %d found", enemy->getTag());
        }
    }
    EnemySprite *enemy = dynamic_cast<EnemySprite*>(this->getChildByTag(i));
    if (enemy == NULL) {

        CCLog("Now enemy with %d is NULL :(", i);
    }

getChildren() の外観では、タグを持つすべての敵がそこにいて、これを出力します。

  • タグ 1000 の敵が見つかりました
  • タグ 1001 の敵が見つかりました
  • タグ 1002 の敵が見つかりました

ゲーム中、これが表示されるまで何度も表示されます。

  • タグ 1000 の敵が見つかりました
  • タグ 1001 の敵が見つかりました
  • タグ 1002 の敵が見つかりました
  • 現在、1001 の敵は NULL です :(

そしてクラッシュします。

私の考えでは、正確にそのオブジェクトをチェック、検証、および印刷したので、これは上記のコードでは不可能なはずです...

しかし、さらに興味深いのは (私だけかもしれませんが、これはばかげた間違いかもしれません)、これです。

 this->getChildByTag(i)

内部的にもランダムに問題が発生します。子をトラバースすると、NULL が見つかり、Cocos2d 内部コードを調べます。

        if(pNode && pNode->m_nTag == aTag)
            return pNode;

その場合、pNode は NULL ではありません (アサートがトリガーされないのはそのためです) が、次のようになります。

http://o7.no/137JXC4 (スクリーンショット)

cocos2d::CCCopying のことは、このプロジェクトではすでに悪夢のようなものです。それを見るたびに、何かが間違っていることがわかり、それが何であるかを見つける方法がわかりません。

release() 削除行に既にブレークポイントを追加しました。呼び出されていません。そして、私が言ったように、私は手動でそのようなことをしていません。

私は Xcode / iOS を使用してデバッグしますが、動作は Android でも同じです (ただし、私のコンピューターでは、Eclipse は特にデバッグ中に Xcode よりも遅くなります)。

ただし、解決策/原因を教えていただくのは難しいと思います。誰かがこの問題に対処する方法を教えてくれたら本当にうれしいです. それは(非常に大きな)コードベース全体でランダムに発生し、この問題を見つける方法が途方に暮れています...

誰かが助けてくれることを願っています!

4

6 に答える 6

1

おっしゃる通り、わかりにくいですが、ここに 2 つのアイデアがあります。

ガード mallocをオンにしてみてください。

あるいは、疑わしいクラス (EnemySprite など) のデコンストラクター/コンストラクターに静的 int カウンターを配置してデクリメント/インクリメントし、ゼロを下回ったときにブレーク/ログすることで何かを得ることができます。

于 2013-05-06T08:31:33.647 に答える
0

Build Settings->Other C Flags->Debug and add -o0フラグを立ててデバッグしてみてください。

于 2014-09-24T12:05:11.210 に答える
0

j私は何の定義しか見ていiませんか?CCLog("Now enemy with %d is NULL :(", i); この行はすでにログに記録されているため、後でクラッシュすると思いますが、ここではクラッシュしません。

于 2013-05-10T05:50:03.833 に答える