我将 Cocos2d-x 用于我从 Cocos2d-iphone 移植的游戏。最初的程序员似乎使用了 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 (这就是断言不触发的原因),但看起来像这样:
在这个项目中,cocos2d::CCCopying 对我来说已经是噩梦了;每次我看到它,我都知道有问题,但我不知道如何找到它。
我已经在 release() 删除行添加了一个断点;它没有被调用。就像我说的,我不会手动做任何类似的事情。
我使用 Xcode / iOS 进行调试,但在 Android 上的行为是相同的(但在我的计算机上,Eclipse 比 Xcode 慢,尤其是在调试期间)。
但是,我知道很难给我一个解决方案/原因;如果有人能告诉我如何解决这个问题,我会非常高兴。它在整个(相当大的)代码库中随机发生,我不知道如何找到这个问题......
我希望有人能帮帮忙!