0

我需要将 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
4

1 回答 1

1
imgInfo->name = [NSString stringWithUTF8String:newImg->name.c_str()];

这是不正确的内存管理。您直接将一个您不拥有的对象分配给另一个对象的实例变量。如果您以相同的方法使用它,它将起作用,但不能保证该对象的生命周期超过当前自动释放池的生命周期。所以最终,实例变量指向垃圾。

理想情况下,您应该使用访问器而不是直接分配实例变量。这是 Cocoa 应用程序中惯用的方法。如果由于某种原因您根本无法使用访问器,那么您需要确保在使用实例变量的任何地方都正确地管理您的内存。

于 2013-06-25T07:42:07.247 回答