【问题标题】:cocos2d-x 3.1 EXC_BAD_ACCESS on Touch event + functioncocos2d-x 3.1 EXC_BAD_ACCESS on Touch 事件+函数
【发布时间】:2014-05-27 10:46:12
【问题描述】:

我是 cocos2d-x 初学者,在使用 TouchBegan 事件 + 函数时遇到问题。 当我使用 xCode(5.1.1 + iPhone sim 7.1) 运行这个简单的代码时,我总是在 [label->setString("Foo Bar");] 点得到 EXC_BAD_ACCESS。

我尝试了几种方法来解决,但我完全被这个问题困住了 2 或 3 天。

有人对错误的观点有任何想法吗?

HelloWorld.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::LayerGradient
{
    public:
    static cocos2d::Scene* createScene();

    virtual bool init();

    bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);


    cocos2d::Label* label;
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

HelloWorld.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}


bool HelloWorld::init()
{

    if(!LayerGradient::initWithColor(Color4B(0, 0, 0, 255), Color4B(50, 50, 50, 255))){
        return false;
    }
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();



    auto label = Label::create("Hello World", "Arial", 112);
        label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));
    this->addChild(label, 1);



    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
    this->getEventDispatcher()->addEventListenerWithFixedPriority(listener, 100);

    return true;
}



bool HelloWorld::onTouchBegan(Touch *touch, Event *event){
    label->setString("Foo Bar");
    return true;
}

谢谢。

【问题讨论】:

    标签: cocos2d-x exc-bad-access cocos2d-x-3.0


    【解决方案1】:

    你的问题出在这一行:

    auto label = Label::create("Hello World", "Arial", 112);
    

    在这一行中,您声明了一个名为label 的新变量,其范围仅适用于init 函数。您还有一个名为label 的类变量,它们不一样。如果你在一个方法中声明一个与类变量同名的变量,它会shadow它。考虑这个例子:

    class A {
        int variable;
    
        void method() {
    
            int variable; // this is not the same thing as the one above
    
            variable = 5; //assignment to local variable
    
            this->variable = 3; //asignment to class variable
    
        }
    }
    

    所以你实际上并没有为你的类变量label 分配任何东西,你稍后会在 touch 方法中引用它。解决此问题的最简单方法是从您的 init() 方法中删除 auto label 处的 auto 关键字。

    【讨论】:

    • 非常感谢您的回答 Losiowaty。我想我对你写的东西理解了一半。我尝试删除 'auto' 并在 'label->setPosition' 行得到 EXC_BAD_ACCESS .. mmm ...
    • 终于如你所说。我一直在尝试使用Label::createWithTTF,由于某种原因它返回了 EXC_BAD_ACCESS 错误。但是 "autodeleted ver" 与Label::create 完全兼容。非常感谢您的建议!
    【解决方案2】:

    正如@Losiowaty 所指出的,使用auto 有时会很危险。

    cocos2d::Label* label = cocos2d::Label::create("Hello World", "Arial", 112);
    

    另外,可能有更好的构造函数可以使用:http://www.cocos2d-x.org/reference/native-cpp/V3.1rc0/db/de4/classcocos2d_1_1_label.html

    【讨论】:

    • 这不会解决他的问题 - 它仍然不会将值(地址)分配给类变量,而是分配给本地变量。
    • 谢谢GameDeveloper,我也试过这段代码,但正如Losiowaty所说,它没有用。还是谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多