0
votes

I create iOS app with Cocos2d v 1.0.1 and Box2d (cocos2d + box2d template). On iPad my app works ok On iPhone 4,4s ( ios versions 5.0.1 , 6.0 , not tested on other iPhones/firmwares) I got EXC_BAD_ACCESS at beginning of my game (after short time of playing) .

myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO  );

I analyzed state of b and Box2d world, and it looks like the bodies list of world is corrupted. Pointer to b contains b2PolygonShape, not a b2Body (I see that in Variables View in Xcode). Sometimes (also only on iPhones), my game begins to behave unexpectedly. I set breakpoints in my update method and realized that Box2d world's body list contatins only one body (but at previous update world contains many bodies, and visually they are on screen on current update).

I checked code of my game, and cannot find the error, or reason of such behavior. I tried to use Analyze feature of Xcode, change Box2d version, and some other things. I couldn't solve this problem for now.
What approaches should I use to debug this crash?
What can I do to research and solve it?

1

1 Answers

1
votes

I have found the error by excluding parts of Box2d-related code from my app. In following code

    CCDelayTime *destroyDelay = [CCDelayTime actionWithDuration:0.001];
    CCCallBlock *destroyBlock = [CCCallBlock actionWithBlock:^{
        b2Body * b = (b2Body *)[bodyVal pointerValue];
        b->SetUserData(NULL);
        [self world]->DestroyBody(b);
    }];
    [self runAction: [CCSequence actions:destroyDelay,destroyBlock, nil]];

pointer b, stored in NSValue, may not be valid when CCCallblock is executed, and this leads to memory errors.

I replaced this code with

NSValue *bodyVal = [NSValue valueWithPointer: body ];
[self.bodiesThatHeroCollidedWith addObject: bodyVal ];

and then in my update: method I cleans the self.bodiesThatHeroCollidedWith array:

for (NSValue *body in self.bodiesThatHeroCollidedWith) {
    b2Body *b = (b2Body *)[body pointerValue];
    b->SetUserData( NULL );
    world->DestroyBody( b );
}
[self.bodiesThatHeroCollidedWith removeAllObjects];