Мне нужно преобразовать NSString в std :: string и успешно это сделать, используя [str UTF8String]
, Но по какой-то причине, когда я пробую это на одной из моих строк NSStrings, я получаю EXC_BAD_ACCESS
ошибка.
Я проверяю это str
не является нулевым, поэтому я не уверен, почему это происходит. Я также пытался убедиться, что str
действительно NSString, но следующее выдает ту же ошибку:
const char* className = class_getName([str class]);
Что мне не хватает?
РЕДАКТИРОВАТЬ: код, который я использую:
NSMutableArray* m_imageInfos; // defined in ClassName.h
RUBEImageInfo *touchedImgInfo; // also defined in ClassName.h
Это проект cocos2d, и в зависимости от игрового процесса я загружаю дополнительные объекты типа RUBEImageInfo
в m_imageInfos. Соответствующий код:
RUBEImageInfo* imgInfo = [[RUBEImageInfo alloc] init];
imgInfo->sprite = sprite;
imgInfo->name = [NSString stringWithUTF8String:newImg->name.c_str()];
std::cout << "loadBody imgInfo name " << [imgInfo->name UTF8String] << "\n";
Std :: cout правильно печатает имя изображения. Я должен добавить, что имя — это конкатенация строки и типа int, например:
std::stringstream sstm;
sstm << img->name << counter;
newImg->name = sstm.str();
В ClassName.mm, CCTouchesBegun я проверяю, к какому объекту b2Body обращаются, а затем перебираю m_imageInfos, чтобы увидеть, какое изображение imageInfo было затронуто:
for(int j=0; j<[m_imageInfos count]; j++) {
RUBEImageInfo *rif = m_imageInfos[j];
if(rif->body == body) {
touchedImgInfo = rif;
printf("ccTouchesBegun touchedImgInfo %p \n", touchedImgInfo);
printf("ccTouchesBegun touchedImgInfo name %p \n", [touchedImgInfo->name UTF8String]);
break;
}
}
Первая распечатка проходит хорошо и дает такой результат:
ccTouchesBegun touchedImgInfo 0x98b84f0
Но вторая распечатка неисправна с EXE_BAD_ACCESS
, Чтобы добавить сложности, это происходит только в большинстве случаев. Один раз в каждые 10-15 попыток работает нормально.
Для полноты кода это RUBEImageInfo.h:
#import "cocos2d.h"
@interface RUBEImageInfo : NSObject {
@public CCSprite* sprite;
@public NSString* name;
@public class b2Body* body;
@public float scale;
@public float angle;
@public CGPoint center;
@public float opacity;
@public bool flip;
@public int colorTint[4];
}
@end
imgInfo->name = [NSString stringWithUTF8String:newImg->name.c_str()];
Это неправильное управление памятью. Вы непосредственно присваиваете объект, которым не владеете, переменную экземпляра другого объекта. Он будет работать, если вы будете использовать его тем же способом, но жизнь этого объекта не гарантируется после жизни текущего пула автоматического выпуска. Так что в конечном итоге переменная экземпляра указывает на мусор.
В идеале вы должны использовать методы доступа вместо непосредственного назначения переменных экземпляра. Это идиоматический подход в приложениях Какао. Если вы просто не можете использовать методы доступа по какой-либо причине, вам нужно быть абсолютно уверенным, что вы правильно управляете своей памятью везде, где используется переменная экземпляра.
Других решений пока нет …