我使用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()外观中,所有带有标签的敌人都在那里并打印出来;
在比赛期间,它会显示很多,直到它显示出来;
并崩溃。
在我看来,上面的代码应该是不可能的,因为我刚刚检查,验证并打印了那个对象......
但更有趣(也许只有我,也许这是一些愚蠢的错误),这个
this->getChildByTag(i)
内部也随机出错;遍历这些孩子,它会在Cocos2d内部代码中找到一个NULL和conk out:
if(pNode && pNode->m_nTag == aTag)
return pNode;
然后pNode不是NULL(这就是断言不触发的原因)但看起来像这样:
在这个项目中,cocos2d :: CCCopying对我来说已经是噩梦了。我每次看到它都知道有些事情是错的,我不知道如何找到它是什么。
我已经在release()删除行添加了一个断点;它没有被召唤。就像我说的那样,我手动不做那样的事。
我使用Xcode / iOS进行调试,但Android上的行为是相同的(但在我的计算机上,Eclipse比Xcode慢,特别是在调试期间)。
我知道很难给我一个解决方案/原因;如果有人能告诉我如何解决这个问题,我会很高兴。它在整个(非常大的)代码库中随机发生,我不知道如何找到这个问题...
我希望有人可以提供帮助!
答案 0 :(得分:3)
有时dynamic_cast返回0甚至很难,它的参数不是0.例如,当您将超类转换为子类(所谓的“向下转换”)时会发生这种情况。有关详细信息,请查看本教程:http://www.cplusplus.com/doc/tutorial/typecasting/
我可以想象,如果列表中的元素具有通用(无关)超类型,则可能是您的问题。
答案 1 :(得分:1)
正如你所说,这很难说,但这里有两个想法。
您可以尝试启用guard malloc。
或者,你可能会从你的可疑类(如EnemySprite的)解构器/构造函数中放入一个静态int计数器来减少/递增,并在它低于零时打破/记录。
答案 2 :(得分:0)
我只看到j
什么是i
的定义?
我相信它在CCLog("Now enemy with %d is NULL :(", i);
之后崩溃了
因为这条线已被记录,所以它绝对不会崩溃。
答案 3 :(得分:0)
默认情况下,CCObjects受AutoReleasePool约束,这意味着Cocos2D-x将管理何时释放该对象。如果对这些对象使用静态构造函数,则可以调用object-&gt; retain()和object-&gt; release(),以便自己管理内存。
来源:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Reference_Count_and_AutoReleasePool_in_Cocos2d-x
答案 4 :(得分:0)
如果某些东西将敌人对象更改为NULL,我会做的是在敌人的地址设置一个数据断点(对于1001)。比,
getChildByTag()
。我会做的是用this->getChildByTag()
替换dynamic_cast<EnemySprite*>(this->getChildren()->objectAtIndex())
,检查是否有任何区别。答案 5 :(得分:0)
在Build Settings->Other C Flags->Debug and add -o0
标记并尝试调试。