简体   繁体   English

在iOS中使用CreateFixture在Box2D中使用EXC_BAD_ACCESS

[英]EXC_BAD_ACCESS in Box2D with CreateFixture in iOS

I have had multiple games on the AppStore for 5-6 years that use Cocos2D and Box2D. 我在AppStore上有5-6年使用Cocos2D和Box2D的多个游戏。 I've never had a problem with any of them crashing. 我从来没有遇到任何崩溃的问题。 Apple is making me update them or they'll be taken off of the AppStore. Apple正在让我更新它们,否则它们将从AppStore中删除。 So I started to update them by updating Cocos2d and Box2d. 因此,我开始通过更新Cocos2d和Box2d来更新它们。 After a few hours dealing with build errors I was ata point where I could test. 处理构建错误几个小时后,我可以进行测试了。 I tested in the simulator on 6 devices spanning different operating system versions. 我在模拟器中的6个设备上进行了测试,这些设备跨越了不同的操作系统版本。 I also tested on my iPhone6 10.3. 我还在iPhone6 10.3上进行了测试。 I even made screen grabs at different sizes. 我什至制作了不同尺寸的屏幕抓图。 I uploaded an archive to TestFlight and then tested that on my device.... CRASH. 我将档案上传到TestFlight,然后在我的设备上对其进行了测试。 I then went back to test on simulator and CRASH. 然后,我回到模拟器和CRASH上进行测试。 Now it crashes every time at the same point. 现在,它每次都在同一时间崩溃。 I have no idea why it worked for so long and now doesn't without any code changes. 我不知道为什么它能工作这么长时间,而现在却没有任何代码更改。

I was getting the crash on CreateBody. 我在CreateBody上崩溃了。 I then moved all the code to after world->Step and now it crashes on CreateFixture. 然后,我将所有代码移至world-> Step之后,现在在CreateFixture上崩溃。 I enabled zombies and that doesn't give me any more insight. 我启用了僵尸,这并没有给我任何更多的见解。

The game begins and it creates 2 b2Body objects and 2 b2Fixture objects (a large ring). 游戏开始,它将创建2个b2Body对象和2个b2Fixture对象(一个大环)。 There is also another b2Body & b2Fixture that you can move up and down (a blimp). 还有另一个b2Body和b2Fixture,您可以上下移动(飞艇)。 The object is to get the blimp to go through the rings. 目的是使飞艇穿过环。 The rings move from right to left. 环从右向左移动。 Once you pass or fail that ring, the ring parts are destroyed and and new ring (2 b2Bodies & 2 b2Fixtures) is created. 一旦您通过或失败该环,环部分将被销毁并创建新的环(2个b2Bodies和2个b2Fixtures)。 This SECOND RING is where the crash happens. 此第二环是发生崩溃的地方。 (Again, for years this has worked perfectly starting with ios 4.3 -> 10) but now trying to update with XCode 8 it won't work (even though I tested for hours and it worked fine yesterday). (同样,多年来,从ios 4.3-> 10开始,它一直完美运行),但现在尝试用XCode 8更新它却行不通(即使我测试了几个小时并且昨天运行良好)。

Here is the ring creation code: (written 4-5 years ago when I was learning Box2D) 这是创建戒指的代码:(在我学习Box2D的4-5年前编写的)

-(void)addRing{

int r = (arc4random() % 250) + 160;
CGPoint p = ccp(SCREEN_WIDTH+100,r);

ring_bottom = [CCSprite spriteWithFile:@"ring_bottom.png"];
[self addChild:ring_bottom z:BLIMP_BOTTOM tag:bTagRingBottom];
ring_bottom.position = ccp(p.x, p.y);

// Define the dynamic body.
//Set up a 1m squared box in the physics world
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x/PTM_RATIO,p.y/PTM_RATIO);
bodyDef.userData = ring_bottom;
bodyDef.fixedRotation=YES;
bodyDef.gravityScale=0;
//bodyDef.position.Set(0.0, 0.1);
_ringBottom = _world->CreateBody(&bodyDef);

b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(0.25, 10.0, b2Vec2(0.0,13.00), 0.0);

// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 10.0f;
fixtureDef.friction = 0.0f;
fixtureDef.isSensor = true;

_ringBottom->CreateFixture(&fixtureDef);

//----------------------------------------------------

ring_top = [CCSprite spriteWithFile:@"ring_top.png"];
[self addChild:ring_top z:GAME_LAYER tag:bTagRingTop];
ring_top.position = ccp(p.x, p.y);

// Define the dynamic body.
//Set up a 1m squared box in the physics world
b2BodyDef bodyDef2;
bodyDef2.type = b2_dynamicBody;
bodyDef2.position.Set(p.x/PTM_RATIO,p.y/PTM_RATIO);
bodyDef2.userData = ring_top;
bodyDef2.fixedRotation=YES;
bodyDef2.gravityScale=0;
_ringTop = _world->CreateBody(&bodyDef2);

b2PolygonShape dynamicBox2;
dynamicBox2.SetAsBox(0.25, 10.0, b2Vec2(0.0,-13.00), 0.0);

// Define the dynamic body fixture.
b2FixtureDef fixtureDef2;
fixtureDef2.shape = &dynamicBox2;
fixtureDef2.density = 10.0f;
fixtureDef2.friction = 0.0f;
fixtureDef2.isSensor = true;

_ringTop->CreateFixture(&fixtureDef2);
}

If I comment out the CreateFixture, It runs perfectly fine. 如果我注释掉CreateFixture,它运行得很好。 I can't do this. 我做不到

The crash is in b2Body.cpp: 崩溃位于b2Body.cpp中:

b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
{

...

fixture->Create(allocator, this, def);

...

}

And in b2Fixture.cpp 并在b2Fixture.cpp中

void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def)
{

...

m_shape = def->shape->Clone(allocator);

...

}

I have 5-6 apps that use Box2d & Cocos2d and I don't want to have to take them off the AppStore but I also can't start over on them. 我有5-6个使用Box2d和Cocos2d的应用程序,我不想将它们从AppStore中删除,但我也无法从头开始。 I have already written a version where the creation happens after world->Step but that didn't change anything, still crashes. 我已经编写了一个版本,其中创建是在world-> Step之后进行的,但是并没有改变任何东西,仍然崩溃。

This is the code that is deleting the bodies in the tick method : 这是删除tick方法中主体的代码:

std::vector<b2Body *>toDestroy;

...

std::vector<b2Body *>::iterator pos2;
    for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
        b2Body *body = *pos2;
        if (body->GetUserData() != NULL) {
            CCSprite *sprite = (CCSprite *) body->GetUserData();
            [self removeChild:sprite cleanup:YES];
        }
        _world->DestroyBody(body);
    }

Hopefully someone can help me save these games from being removed from the AppStore. 希望有人可以帮助我保存这些游戏,避免将其从AppStore中删除。 Any help is appreciated and keep in mind I haven't used Box2d in years so frankly I don't remember much about it. 感谢您提供任何帮助,并请记住,多年来我没有使用Box2d,所以坦率地说我对此不太记得。

EDIT: I reverted back to the older version of Cocos2d and I'm back to crashing on CreateBody. 编辑:我回到了Cocos2d的旧版本,并且我回到了CreateBody崩溃的状态。 More specifically: 进一步来说:

b2BlockAllocator.cpp b2BlockAllocator.cpp

void* b2BlockAllocator::Allocate(int32 size){

...

    if (m_freeLists[index]){
        b2Block* block = m_freeLists[index];
        m_freeLists[index] = block->next; <--------------CRASH
         return block;
    } else {

     ...

    }
}

I always crash on index 6 我总是在索引6上崩溃

> Printing description of this->m_freeLists:
(b2Block *[14]) m_freeLists = {
  [0] = 0x0000000000000000
  [1] = 0x0000000103ca4060
  [2] = 0x0000000103ca0080
  [3] = 0x0000000100b30120
  [4] = 0x0000000000000000
  [5] = 0x0000000103ca80a0
  [6] = 0x0000000300b2c180
  [7] = 0x0000000104240000
  [8] = 0x0000000000000000
  [9] = 0x000000010423c140
  [10] = 0x0000000000000000
  [11] = 0x0000000000000000
  [12] = 0x0000000000000000
  [13] = 0x0000000000000000
}

在此处输入图片说明

So next in block is null so it crashes. 因此,block中的next为null使其崩溃。 Another forum said a person with very similar code was trying to destroy same object multiple times. 另一个论坛说,一个代码非常相似的人正试图多次摧毁同一物体。 I don't see that happening. 我看不到这种情况。

So the problem, as PaulMcKenzie pointed out, is the way that I am destroying bodies. 因此,正如PaulMcKenzie所指出的那样,问题是我摧毁尸体的方式。 This was originally written for Xcode 4.3 and now updating for Xcode 8.3 I have a crash problem. 这最初是为Xcode 4.3编写的,现在为Xcode 8.3更新了,我遇到了崩溃问题。 I have no knowledge of Box2D anymore so I went for the quick fix of Destroying the fixtures and hiding the sprites and then destroying the bodies after they go off the screen. 我再也不知道Box2D了,所以我去快速修复了破坏固定装置并隐藏精灵的情况,然后在它们离开屏幕后销毁了它们。 This seems to work for me for now and since I can't spend time fixing it with (erase(remove_if()), the right way, it will do for now. 这似乎现在对我来说是有效的,因为我不能花时间用(erase(remove_if())来修复它,所以正确的方法现在就可以了。

I am Answering this because this is the offending code located in the tick method: 我正在回答这个问题,因为这是位于tick方法中的有问题的代码:

std::vector<b2Body *>::iterator pos2;
for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
    b2Body *body = *pos2;
    if (body->GetUserData() != NULL) {
        CCSprite *sprite = (CCSprite *) body->GetUserData();
        [self removeChild:sprite cleanup:YES];
    }
    _world->DestroyBody(body);
}

And it is important to rewrite this in the proper way to destroy a b2Body. 因此,以正确的方式销毁b2Body来重写它很重要。

If someone writes the proper way to destroy the body I will mark it as the correct answer. 如果有人写出破坏尸体的正确方法,我将其标记为正确答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM