0

NSString を std::string に変換する必要があり、[str UTF8String]. しかし、何らかの理由で、NSStrings の 1 つで試してみると、EXC_BAD_ACCESSエラーが発生します。

strnull ではないことを確認しているので、なぜこれが起こっているのかわかりません。strまた、それが実際に NSStringであることを確認しようとしましたが、以下は同じエラーをスローします:

const char* className = class_getName([str class]);

私は何が欠けていますか?

編集:私が使用しているコード:

NSMutableArray* m_imageInfos; // defined in ClassName.h
RUBEImageInfo *touchedImgInfo; // also defined in ClassName.h

これは cocos2d プロジェクトで、ゲーム フローに応じて、タイプの追加オブジェクトをRUBEImageInfom_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

しかし、2 番目の出力はEXE_BAD_ACCESS. さらに複雑なことに、これはほとんどの場合にしか発生しません。10 ~ 15 回の試行ごとに 1 回、正常に動作します。

コードを完全にするために、これは 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 に答える