2011-04-20 154 views
0

我有以下代码:的cocos2d Box2D的精灵位置崩溃

for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) 
{ 
    if (b->GetUserData() != NULL) 
    {    
     CCSprite *itemSprite = (CCSprite*)b->GetUserData(); 
     CGSize SpriteSize; 
     SpriteSize.height = itemSprite.contentSize.height; 
     SpriteSize.width = itemSprite.contentSize.width; 
     CGPoint SpritePosition=[itemSprite position];   
    } 
} 

刚刚获得精灵的位置,但这个方案中有时会崩溃:

SpriteSize.height = itemSprite.contentSize.height; 

这行:

CGPoint SpritePosition=[itemSprite position]; 

我正在使用cocos2d .99.5。

Edit:这里是我的崩溃日志:

异常类型:EXC_BAD_ACCESS(SIGBUS) 异常代码:KERN_PROTECTION_FAILURE在0x0000000f 坠毁主题:0

Thread 0 Crashed: 
0 libobjc.A.dylib     0x00002666 objc_msgSend_stret + 14 
1 ShootTheMonkey     0x0004c066 -[LevelFour ccTouchBegan:withEvent:] (LevelFour.mm:1432) 
2 ShootTheMonkey     0x00321bf0 -[CCTouchDispatcher touches:withEvent:withTouchType:] (CCTouchDispatcher.m:238) 
3 ShootTheMonkey     0x00322454 -[CCTouchDispatcher touchesBegan:withEvent:] (CCTouchDispatcher.m:305) 
4 ShootTheMonkey     0x003240ec -[EAGLView touchesBegan:withEvent:] (EAGLView.m:318) 
5 UIKit       0x00053d72 -[UIWindow _sendTouchesForEvent:] + 254 
6 UIKit       0x000536fe -[UIWindow sendEvent:] + 74 
7 UIKit       0x0004f320 -[UIApplication sendEvent:] + 260 
8 UIKit       0x0004ec8c _UIApplicationHandleEvent + 4772 
9 GraphicsServices    0x00003b2c PurpleEventCallback + 660 
10 CoreFoundation     0x00022d96 CFRunLoopRunSpecific + 2214 
11 CoreFoundation     0x000224da CFRunLoopRunInMode + 42 
12 GraphicsServices    0x000030d4 GSEventRunModal + 108 
13 GraphicsServices    0x00003180 GSEventRun + 56 
14 UIKit       0x0000342a -[UIApplication _run] + 374 
15 UIKit       0x00001954 UIApplicationMain + 636 
16 ShootTheMonkey     0x0000377e main (main.m:13) 
17 ShootTheMonkey     0x0000373c start + 32 
+0

崩溃转储应该给你一些有关错误的确切原因的有价值的信息。你可以发布吗? – Ben 2011-04-20 07:20:13

+1

我想,那个b2Body里面没有任何精灵。这是一个很好的习惯,将迭代通过body列表更改为如下所示:for(b2Body * body = world-> GetBodyList(); body!=无; body => Body-> GetNext()) \t { \t \t BodyNode * bodyNode =(BodyNode *)body-> GetUserData(); \t \t如果(bodyNode = NULL && bodyNode.sprite =零!) \t \t { ....} – gixdev 2011-04-20 09:06:36

+0

@gixdev:UR答案可能是有帮助的..... u能透露具体细节在这个答案节问题,请..... – Rony 2011-04-20 10:48:18

回答

1

既然你做不发布崩溃转储或堆栈跟踪,我只能猜测。 AFAIK至少有两个原因:

  1. 您将多个类的对象分配到body->SetUserData()。当用户数据实际上不是CCSprite时将用户数据转换为CCSprite时发生崩溃。虽然我怀疑是这种情况,因为通常人们将相同类别的对象分配给它。

  2. 第二个原因更可能发生,因为人们通常依赖CCLayer来保留其CCSprite子项(而不是明确保留它们)。当你从父CCLayer中删除CCSprites时,后者释放前者,如果保留计数== 0(非常可能),CCSprites将从堆中释放。但请记住,有些b2Body仍然通过用户数据属性持有指向这些CCSprites的指针?那么当你遍历所有的实体并尝试使用仍然附加到用户数据的发布的CCSprites时会发生什么?崩溃!

解决这个问题的办法是,你需要删除的尸体时,其对应的精灵从他们CCLayer删除,方法是子类CCSprite添加指向b2Body伊娃,或者通过包装两个对象(即精灵和身体)在另一个类。然后添加代码以在精灵即将被解除分配时移除主体。

希望这会有所帮助。如果没有,请发布更多详细信息(崩溃转储或堆栈跟踪)。

+0

我确实解决了这个问题 – Rony 2011-04-21 12:59:36

1

那么,我们知道的是,精灵被分配给userData,并在稍后解除分配。我看到你分配的精灵是一个自动释放对象,更可能意味着超出范围的精灵已经收到释放按摩。为了确保它是真的,请尝试创建精灵,如下所示:[[CCSprite alloc] initWithSprite:@"apple.png"]; 但是,请记住,稍后您必须释放它。
如果它适合你,请使用上面的建议。

+0

我以两种方式声明精灵,这个精灵分配给用户数据....这个声明都需要我......猴子= [CCSprite spriteWithSpriteFrameName:@“ BackMonkey_animation01_pad.png“];和水果= [CCSprite spriteWithFile:[NSString stringWithFormat:@“Fruit%d_pad.png”,(arc4random()%(2 - 1 + 1)+ 1)]]]; – Rony 2011-04-21 04:41:01

+0

,它并没有像现在这样应对?确定,只要确定问题的原因是释放你的对象 - 尝试启动[[CCSprite alloc] initWithSpriteFrameName:frameName] – gixdev 2011-04-21 09:30:19