2

問題の概要: アプリを起動して [New Game] を押すCCDirectorと、GameScene に遷移していました。そこに、32 個GamePieceのオブジェクトを追加します。これらのオブジェクトは、次のようにタッチ イベントを処理します。

@interface GamePiece : NSObject <CCTargetedTouchDelegate>{  

    CCSprite* sprite;

    NSInteger row;
    NSInteger column;

}

//-(void)moveToRow:(NSInteger)newRow column:(NSInteger)newColumn;
-(id)initWithRow:(NSInteger)aRow column:(NSInteger)aColumn tag:(NSInteger)tag parent:(CCNode*)parent;
+(id)gamePieceWithRow:(NSInteger)aRow column:(NSInteger)aColumn tag:(NSInteger)tag parent:(CCNode*)parent;

@end

GamePiece.m:

...
- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    CGPoint touchLocation = [GameScene locationFromTouch:touch];

    CCLOG(@"(%i, %i)", row, column); //<-----THIS!!!

    //Crash never makes it here....

    // Check if this touch is on the Spider's sprite.
    BOOL isTouchHandled = CGRectContainsPoint([sprite boundingBox], touchLocation);
    if (isTouchHandled){        
        id parent = sprite.parent;
        [parent gamePieceSelected:self inRow:row column:column];
    }

    return isTouchHandled;
}

...

- (void)dealloc {
    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; //Important...
    [super dealloc];
}
@end

では、32 ピースをロードした後、次のメソッドを使用してさらにピースをロードします。

[parent gamePieceSelected:self inRow:row column:column];

次のように: (GameScene.m)

-(void)gamePieceSelected:(GamePiece*)aGamePiece inRow:(NSInteger)row column:(NSInteger)column{
    [self removeChildByTag:18 cleanup:YES];
    //Array of index Path!!! row = row, section = column
    NSArray* moves = [self availableMovesForRow:row column:column];

    for(NSIndexPath* index in moves){ //Please forgive me for using NSIndexPath!! 
        [GamePiece gamePieceWithRow:[index row] column:[index section] tag:18 parent:self];
    }
}

基本的に、 をタップすると、tag = 18GamePieceの他のGamePieceオブジェクトが追加されます。次に、このタグを使用して「新しい」GamePieceオブジェクトを削除し、他のオブジェクトを追加します。

私の問題?

をテーピングした後GamePiece、「新しい」ゲーム ピースが適切に表示されますが、複数回タップするとクラッシュします。つまり、 をタップするGamePieceと、新しい gamePieces が表示されます。次に、別の をタップするGamePieceと、クラッシュを待つ心臓に手を置きます..クラッシュするときもあれば、クラッシュしないときもあります... 3回目、4回目、5回目...など。クラッシュする前に10回タップ:P ...とてもランダム....

私の理論:

コメント行を参照してください//<------THIS。同時に多数のオブジェクトがロードされているため、 if ステートメントを満たす がCCLOG見つかるまで、画面をタップするたびに が任意の回数呼び出されます。GamePieceGamePiece

クラッシュすると (スタック トレースやメッセージなしで)、これCCLOGが数回呼び出され、if ステートメント内には決して作成されません!! GamePieceによって削除されたタッチメッセージを送信しようとしているからだと思いますremoveChildWithTag:..しかし、私はすでに[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];deallocを呼び出しており、これは非常に重要な事実につながります:

をタップしてから数秒待ってからGamePiece別のタップをすると、クラッシュしない可能性が高くなります!!

dealloc を呼び出し、タッチ デリゲートを削除する時間を与えているような気がします...

EDIT:CCLOG dealloc に追加することが思い浮かびましたが、呼び出されませんでした... END EDIT

これが明らかかどうかはわかりませんが、新しく追加された GamePieces を削除しないと、ゲームがクラッシュすることはありません...しかし、それらを削除する必要があります :P

助けてください、私は何日もこの問題と戦ってきました >.

4

1 に答える 1

2

これ!!:

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:-1 swallowsTouches:YES]; //Important...

史上最大のミスでした!!

このきちんとしたコード:

[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];

実際にはデリゲートを保持します...そして私はdeallocに到達することはなく、touchdispatcherからDelegateを削除して大惨事を引き起こすこともありません...


編集:

わかりました、誰かが私がデリゲートを削除することになった場所を知りたがっています!そして、私はそれについて言及しなかったことに驚いています!

- (void)onExit {
    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
    // Never forget this!!
    [super onExit];
}
于 2011-02-25T21:47:22.290 に答える