EXC_BAD_ACCESS при доступе к статическому члену?

Я разработал игру на платформе 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;
}
}

1

Решение

Основываясь на комментариях к вашему вопросу, вашей проблемой может быть порядок инициализации статических данных. Чтобы быть более конкретным, я думаю, что возможно, что статический 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;
}
}

Что это делает для того, чтобы при попытке доступа к статическим данным о членах они уже были инициализированы. Это происходит потому, что все ваши статические данные-члены теперь определены внутри функции как статические, и для доступа к ним вы должны вызвать эту функцию, и компилятор генерирует код, чтобы убедиться, что эта функция вызывается в первый раз (и только в первый раз). ) ваши данные составлены и инициализированы должным образом, что, в свою очередь, означает, что при первой попытке доступа к этим данным, где бы и когда бы они ни находились, ваши данные правильно инициализируются.

0

Другие решения

Это была действительно проблема инициализации, мне просто пришлось переместить код из конструкции в bool AppDelegate :: applicationDidFinishLaunching (), и это сработало!

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector