1

我在 Cocos2d-x v2 平台上开发了一款游戏,我从 Android 开始,在 Eclipse 上完全完成编码后,我在 Xcode 上使用相同的代码创建和 iOS 版本。添加所有必需的库后,我成功编译了代码。然而,游戏在 iOS 设备上运行时会挂起,尽管它在 Android 上运行没有任何问题。我尝试了模拟器和 iPod,但从静态方法访问静态成员时总是得到 EXC_BAD_ACCESS。静态成员总是指向 0x0!!这是代码的摘录:\

AppDelegate.cpp

#include "AppDelegate.h"
#include "NASEncData.h"
AppDelegate::AppDelegate()
{
    ep = NASEncData::sharedUserData();
}

NASEncData.h

namespace CocosNas
{
    class NASEncData : public CCObject
    {
public:
        static NASEncData* sharedUserData();

private:
        NASEncData();

        static void initXMLFilePath();

        static std::string m_sFilePath;
    }
}

NASEncData.cpp

#include "NASEncData.h"


NASEncData* NASEncData::sharedUserData()
{
    initXMLFilePath();

    // only create xml file one time
    // the file exists after the programe exit
    if ((! isXMLFileExist()) && (! createXMLFile()))
    {
        return NULL;
    }

    if (! m_spUserData)
    {
        m_spUserData = new NASEncData();
    }

    return m_spUserData;
}

void NASEncData::initXMLFilePath()
{
    if (! m_sbIsFilePathInitialized)
    {
        m_sFilePath += CCFileUtils::sharedFileUtils()->getWriteablePath() + NASENCDATA_XML_FILE_NAME;                  <----error happens here
        m_sbIsFilePathInitialized = true;
    }   
}
4

2 回答 2

0

根据您对问题的评论,您的问题可能是静态数据的初始化顺序。更具体地说,我认为静态AppDelegate实例有可能在NASEncData. 这个问题也可以解释你在不同平台上看到不同行为的事实,因为不相关的静态数据的初始化顺序取决于编译器和链接器。

要解决此问题,您可以NASEncData像这样更改:(请注意,这只是一种可能的解决方法,尽管如果静态的初始化顺序确实是您的问题,我认为这是最简单和最好的解决方案,除了重新设计您的代码以便您不必依赖静态成员。)

NASEncData.h

namespace CocosNas
{
    class NASEncData : public CCObject
    {
    public:
        static NASEncData* sharedUserData();

    private:
        NASEncData();

        static void initXMLFilePath();

        // Note how the stuff below this line have changed
        struct StaticData
        {
            std::string m_sFilePath;
            // Put other static members here
            //   (e.g. m_sbIsFilePathInitialized, m_spUserData, etc.)
            // Put a proper constructor here if needed
        };

        static StaticData & getStaticData ()
        {
            static StaticData s_data;
            return s_data;
        }
    }
}

NASEncData.cpp

void NASEncData::initXMLFilePath()
{
    if (! m_sbIsFilePathInitialized)
    {
        // Note the change in accessing m_sFilePath
        // You should access all your static members like this
        getStaticData().m_sFilePath +=
            CCFileUtils::sharedFileUtils()->getWriteablePath() +
            NASENCDATA_XML_FILE_NAME;
        getStaticData().m_sbIsFilePathInitialized = true;
    }   
}

这样做可以确保当您尝试访问静态成员数据时,它们已经被初始化。发生这种情况是因为您的所有静态成员数据现在都在函数内部定义为静态的,并且要访问它们,您必须调用该函数,并且编译器会生成代码以确保第一次调用该函数(并且仅是第一次) 您的数据已正确构建和初始化,这反过来意味着您第一次实际尝试访问此数据时,无论何时何地,您的数据都已正确初始化。

于 2013-03-11T16:35:20.137 回答
0

这确实是一个初始化问题,我只需将代码从构造移动到 bool AppDelegate::applicationDidFinishLaunching() 并且它起作用了!

于 2013-03-12T07:39:20.143 回答