1

これは、iPhone ゲームの開発中に何時間も費やしました。どんな助けでも大歓迎です!

設定

  • アーク
  • Cocos2d 2.0

問題

  • CCLabelTTF に文字列を設定したときの EXC_BAD_ACCESS
  • 5回の試行ごとに約1回発生します

コード

次のコードは、クラス LevelSelectionLayer からのものです。このクラスは、レベルのグリッドとタッチ操作を処理する別のクラスへのデリゲートです。

LevelSelectionLayer.h 内

@property (strong) NSArray *difficulties;
@property (strong) CCLabelTTF *difficultyLabel;
@property (strong) SlidingMenuGrid *slidingMenuGrid;

LevelSelectionLayer.m 内

-(id) init
{
    if (self = [super init]) {
        self.difficulties = [[NSArray alloc] initWithObjects:@"Easy", @"Intermediate", @"Hard", nil];

        [self initDifficultyLabel];
        [self initGrid];
    }
    return self;
}

-(void) initDifficultyLabel
{
    CGSize size = [[CCDirector sharedDirector] winSize];
    self.difficultyLabel = [[CCLabelTTF alloc] initWithString:[self.difficulties objectAtIndex:0] fontName:FONT_BOLD fontSize:18.0f];
    self.difficultyLabel.position = ccp(size.width / 2 + 3, size.height / 2 + 63);
    self.difficultyLabel.color = CCC3_DARK_COLOR;
    [self addChild:self.difficultyLabel z:5];
}

LevelSelectionLayer.m 内 (続き)。上記のグリッド クラスから呼び出されるデリゲート メソッドです。

-(void) slidingGridDidChangePage
{
    // Get curent page
    int currentPage = self.slidingMenuGrid.iCurrentPage;
    CCLOG(@"currentPage:%d", currentPage); // Always prints correct number

    // Adjust pagination display
    for (int i = 0; i < NUM_PAGES; i++) {
        CCSprite *bub = [self.pageBubbles objectAtIndex:i];
        if (i == currentPage) {
            bub.displayFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"pageSelected.png"];
        }
        else {
            bub.displayFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"page.png"];            
        }
    }

    // Adjust difficulty labeL
    /******* BREAKS HERE *******/
    self.difficultyLabel.string = (NSString *)[self.difficulties objectAtIndex:currentPage];
    //self.difficultyLabel.string = @"Test"; // Breaks every once in a while as well
}
4

2 に答える 2

0

私は同じ問題だと思うことに遭遇しています。これは、デバイスのリリース ビルドでのみ発生します。ゾンビ検出を有効にすると、ラベルを作成した後の次の行で発生する、割り当て解除されたオブジェクト (私の CCLabelTTF) で「setPosition」メソッドが呼び出されているという警告がクラッシュ時に表示されます。何らかの理由で、ラベルが作成されてからメッセージを送信する前に、ARC によってラベルが解放されているようです。役立つ可能性のあるその他の情報: __unsafe_unretained ディレクティブで宣言された ivar にラベルを割り当てています。これは、ラベルへの「弱い」参照を維持して、後でそれを取得することなく変更できるようにするためです。タグを介した親 (ラベルは、それが作成されたレイヤーの子として追加され、それを保持する必要があります)。これは、ラベルを設定するために一時変数を使用する場合には発生しません。また、他のすべての CCNode サブクラスが割り当てに関してまったく同じように動作することも奇妙ですが、この問題は CCLabelTTF でのみ発生しています。

編集:また、CCLabelTTFの便利なメソッド(自動解放されたオブジェクトを返す)の1つを使用してラベルを作成していることにも言及する価値があるため、理論的には、オブジェクトは作成された関数の範囲外でも、自動リリース プールが空になります。

編集:私は私の問題を解決しました。OPに役立つかどうかはわかりませんが、ここにあります:__unsafe_unretainedの代わりに__weakを使用してください。私の知る限り、これは iOS 5.0 以降をサポートするアプリでのみ機能しますが、私にとってはそれで問題ありません。現時点では、それ以下のものをサポートする予定はありません。

于 2012-08-30T17:52:20.520 に答える
0

おそらく、アプリのフロー中のどこかで problemLabel が解放されます。レイヤーが作成された直後にレイヤーに追加しているため(レイヤーを削除するかレイヤーを解放するまで保持されます)、割り当ててどこでも解放する必要はありません。

于 2012-08-25T19:48:54.483 に答える