2016-06-11 3 views
1

cocos2d-x를 시작하면서 문제가 발생했습니다. 코드 아래에 s->getChildrenCount();에 읽기 액세스 위반 오류가 발생합니다.Sprite :: create() 다음에 Sprite 포인터 멤버 변수가 뒤틀림

HelloWorldScene.h

class HelloWorld : public cocos2d::Layer 
{ 
public: 
    static cocos2d::Scene* createScene(); 
    virtual bool init(); 
    void update(float) override; 
    CREATE_FUNC(HelloWorld); 

private: 
    cocos2d::Sprite* s; 
}; 

HelloWorldScene.cpp

Scene* HelloWorld::createScene() 
{ 
    auto scene = Scene::create(); 
    auto layer = HelloWorld::create(); 
    scene->addChild(layer); 
    return scene; 
} 
bool HelloWorld::init() 
{ 
    if (!Layer::init()) 
    { 
     return false; 
    } 

    s = Sprite::create(); 
    this->scheduleUpdate(); 
    return true; 
} 
void HelloWorld::update(float delta) 
{ 
    int k = s->getChildrenCount(); 
    ... 
} 

내 생각 엔 s는 허상 포인터가되고 그것을 참조 카운팅 함께 할 수있는 뭔가가 있다는 것입니다. 참조 계산이 어떻게 작동하는지 읽었지만 완전히 이해하지 못했습니다.

init 끝에 스프라이트가 어떻게 파괴 될 수 있습니까? 누가 그것을하고 있습니까?

이 문제를 해결하는 적절한 방법은 무엇입니까? 을 Sprite::create() 후에 수행하고 HelloWorldScene 소멸자를 s->release()과 함께 추가 하시겠습니까? 이 경우 기존 C++ newdelete을 사용하는 것보다 이점이 없습니다.

답변

0

우선 매달리지 포인터가 있지만 생성 된 포인터가 더 이상 존재하지 않으며 s은 이제 nullptr입니다. 이 때문에 getChildrenCount() 메서드에 액세스하려고하면 액세스 위반 오류가 발생합니다.

create() 메소드를 사용하여 생성 된 객체는 생성 된 메소드가 끝나는 즉시 해제 될 것으로 평가됩니다. 즉, 개체에 참조가없고 유지 표시되지 않으면 생성 된 개체가 해체됩니다. 이 동작이 변경되기를 원하면 이미 종결 된 것처럼 retain 및 release를 호출해야합니다. newdelete를 사용하여 비교 일반적으로 s->retain()s->release(), 또는 참조 카운팅의 장점

하나는 당신이 당신의 클래스 즉, 외부 데이터 회원에 대해 걱정할 필요가 없다는 것입니다. 삭제를 호출하면의 리소스가 더 이상 사용되지 않는 것이 확실합니까? 이 질문은 참조 횟수 및 유지/해제 메커니즘을 사용하여 불필요하게됩니다.

+0

네 말이 맞아, 나는 실수를했다. 이것은 널 포인터이고 매달려있는 포인터가 아니다. "create() 메소드를 사용하여 생성 된 객체는 생성 된 메소드가 끝나는 즉시 해제 될 것으로 평가됩니다." C++에서는 어떻게 가능합니까? – takfuruya

+0

좋은 질문이지만 의견에 쉽게 답변하지는 못합니다. C++ 참조 계산 및 스마트 포인터를 검색해보십시오. –