cocos2d box2d sprite position crash

0

I have the following code:

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];           
    }
}

Just get the position of sprite, but this program crash sometimes in:

SpriteSize.height = itemSprite.contentSize.height;

and this line:

CGPoint SpritePosition=[itemSprite position];

I am using cocos2d .99.5.

Edit: here is my crash log:

Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000f Crashed Thread: 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
cocos2d-iphone
asked on Stack Overflow Apr 20, 2011 by Rony • edited Mar 30, 2014 by Anatoliy Nikolaev

2 Answers

1

Since you do not post the crash dump or stack trace, I can only guess. AFAIK there are at least two reasons:

  1. You assign objects of multiple classes to body->SetUserData(). The crash happens when you cast the user data to CCSprite when it's in fact not a CCSprite. Although I doubt this is the case since usually people assign objects of the same class to it.

  2. The second reason is more likely to happen due to the way people usually depend on CCLayer to retain its CCSprite children (rather than explicitly retaining them). When you remove the CCSprites from the parent CCLayer, the latter releases the former and if retain count == 0 (very likely) the CCSprites are released from the heap. But remember that some of b2Bodies are still holding the pointers to these CCSprites through the user data attributes? So what happen when you iterate over all the bodies and try to use the released CCSprites that are still attached to the user data? Crash!

The way to fix this is that you need to remove the bodies when their corresponding sprites are removed from their CCLayer, by either subclassing CCSprite to add an ivar that points to b2Body, or by wrapping both objects (i.e sprite and body) in another class. Then add code to remove the body when the sprite is about to be de-alloc-ed.

Hope this helps. If not, please post more details (crash dump or stack trace).

answered on Stack Overflow Apr 20, 2011 by Lukman
1

Well, what we know for sure is the sprite was assigned to userData and it was later deallocated. I see that your assigned sprite was an autoreleased object and more likely it means that out of the scope sprite has received a release massage. To make sure that it is true, try to create sprite as follows: [[CCSprite alloc] initWithSprite:@"apple.png"]; But remember later you must release it.
If it worked for you, use the suggestion that above.

answered on Stack Overflow Apr 20, 2011 by gixdev

User contributions licensed under CC BY-SA 3.0