2011-04-20 155 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