2011-01-15 18 views
0

私に同行してください私は長いコードを投稿しようとしています。 私はCCSpriteをサブクラス化しています:CCSpriteのサブクラスでアクションを実行する

@interface Character : CCSprite { 
    } 
    -(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect; 
    @end 

    @implementation Character 
    -(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect 
    { 
     NSLog(@"in initWithTexture"); 
     if((self=[super initWithTexture:texture rect:rect])) 
     { 
     } 
     return self; 
    } 
    -(void) dealloc 
    { 
     NSLog(@"character dealloced"); 
     [super dealloc]; 
    } 
    @end 

質問#1:それは正しいのですか?

私はこのスプライトをクラス変数として含み、別のCCSpriteを含むレイヤーを持っています。

Character *characterSprite; 
CCSprite *burpSprite; 

この層はまた、2つのCCAnimationオブジェクトを有する:このクラスで

CCAnimation *burpAnim; 
CCAnimation *burpParticlesAnim; 

Iは、2つの方法があります - (ボイド)loadBurpAnimationと、 - (void)unloadBurpAnimation;

私はこのように書きされ、スレッドでげっぷアニメーションをロードし、それを再生するには、メインスレッド上でメソッドを呼び出す必要が
-(void) loadBurpAnimation { 
     NSString* burpFile; 
     NSString* burpFilePVR; 

     NSString* burpParticlesFile; 
     NSString* burpParticlesFilePVR; 

     burpFile = @"latestBurp1-1.plist"; 
     burpFilePVR = @"latestBurp1-1.pvr.ccz"; 
     burpParticlesFile = @"burpParticles1-1.plist"; 
     burpParticlesFilePVR = @"burpParticles1-1.png"; 

     [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpFile texture:[[CCTextureCache sharedTextureCache] addImage:burpFilePVR]]; 
     [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpParticlesFile texture:[[CCTextureCache sharedTextureCache] addImage:burpParticlesFilePVR]]; 

     NSMutableArray *burpFrames = [NSMutableArray array]; 
     for(int i = 231; i <= 268; ++i) { 
      [burpFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"burp.%d.png", i]]]; 
     } 
     burpAnim = [[CCAnimation alloc] initWithFrames:burpFrames delay:0.04f]; 
     [burpFrames removeAllObjects]; 

     //Burp Particles 
     [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:burpParticlesFile]; 
     NSMutableArray *burpParticlesFrames = [NSMutableArray array]; 
     for(int i = 3; i <= 37; ++i) { 
      [burpParticlesFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Burp_%05d.png", i]]]; 
     } 

     burpParticlesAnim = [[CCAnimation alloc] initWithFrames:burpParticlesFrames delay:0.04f]; 
     [burpParticlesFrames removeAllObjects]; 
} 

-(void) unloadBurpAnimation { 

    [burpAnim release]; 
    [burpParticlesAnim release]; 
} 

-(void) loadAnimation { 
    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; 

    [dictLock lock]; 

    if([EAGLContext setCurrentContext:auxEAGLcontext]) { 
     [self loadBurpAnimation]; 
       [self performSelectorOnMainThread:@selector(burpAnimation) withObject:nil waitUntilDone:NO]; 
     } else { 
     CCLOG(@"cocos2d: TetureCache: EAGLContext error"); 
    } 
    [dictLock unlock]; 
    [autoreleasepool drain]; 
} 

私は「個別のアニメーションをロードする方法があります知っていますasynchAddImage "ですが、これはここでの問題ではありません。

-(void) burpAnimation { 

    CCAction *burpAction = [CCSequence actions: 
          [CCAnimate actionWithAnimation:burpAnim restoreOriginalFrame:NO], 
          [CCCallFunc actionWithTarget:self selector:@selector(animationDone)],nil]; 
    CGSize winSize = [CCDirector sharedDirector].winSize; 
    characterSprite = [[Character alloc] initWithSpriteFrameName:@"burp.231.png"]; 
    characterSprite.position = ccp(winSize.width/2, winSize.height/2); 
    [characterSprite setScale:1.5]; 

    CCAction *particlesAction = [CCSequence actions: 
          [CCAnimate actionWithAnimation:burpParticlesAnim restoreOriginalFrame:NO], 
          nil]; 
    burpSprite = [[CCSprite alloc] initWithSpriteFrameName:@"Burp_00003.png"]; 
    burpSprite.position = ccp(winSize.width/2-50, winSize.height/2-80); 

    [self addChild:characterSprite]; 
    [characterSprite release]; 

    [self addChild:burpSprite]; 
    [burpSprite release]; 

    [characterSprite runAction:burpAction]; 
    [burpSprite runAction:particlesAction]; 
} 

CCCallFuncセレクタは、アニメーションの後に呼び出されたときに、私が直面しています本当の問題は次のとおりです。

- (void)animationDone { 
    //Here characterSprite retain count is 2 
     NSLog(@"B4 stop char rc %d", [characterSprite retainCount]); 

     [characterSprite stopAllActions]; 

     //Here characterSprite retain count is still 2 
     NSLog(@"B4 stop char rc %d", [characterSprite retainCount]); 

    [self removeChild:characterSprite cleanup:YES]; 

>>>  //Here characterSprite retain count is 1 WHY? 
>>>  NSLog(@"char rc %d", [characterSprite retainCount]); 

     //Here burpSprite retain count is 2 
     NSLog(@"particles rc %d", [burpSprite retainCount]); 

    [burpSprite stopAllActions]; 

     //Here burp retain count is 1 
     NSLog(@"particles rc %d", [burpSprite retainCount]); 
    [self removeChild:burpSprite cleanup:YES]; 

     // releases the animation objects 
    [self unloadBurpAnimation]; 

     //Here burpAnim retainCount = 1 
     NSLog(@"BURP ANIM rc = %d", [burpAnim retainCount]); 

     //Here burpParticlesAnim retainCount = 0 , crashes if print here obviously. 
     //NSLog(@"Particles ANIM rc = %d", [burpParticlesAnim retainCount]); 

     [[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames]; 
    [[CCTextureCache sharedTextureCache] removeUnusedTextures]; 
} 

二つの問題: 私は1に等しく、その保持カウントを取得characterSpriteを削除したものの。 私はburpAnimをリリースしましたが、このCCSpriteFrameCacheはspriteFramesを削除できないため、テクスチャも削除されないため、保持カウントは1になります。

これらの問題の両方が相互にリンクされていますか? これを読んでいただきありがとうございました、どんな助けも大歓迎です。

答えて

0

二つの問題:私は characterSpriteを削除したものの、私はその1に等しい 数を保持して取得します。私は を持っていますが、私はその の数が1と等しいので、 CCSpriteFrameCacheはスプライトフレーム を削除できないため、テクスチャは も削除されません。

最初の問題は、retainCountに電話していて、返された番号が意味があると考えていることです。

オブジェクトの保持カウントは、常にデルタとして扱う必要があります。あなたが何かを保持することによってそれを増やすなら、あなたは解放するか、または他のどこかでオートレリースすることによってそれを減らさなければなりません。どこがオブジェクトへの参照を「所有しているか」に完全に依存します。

他のいくつかの疑問のビットがあります。

burpAnim = [[CCAnimation alloc] initWithFrames:burpFrames delay:0.04f]; 
    [burpFrames removeAllObjects]; 

は、なぜあなたは、その後​​、その後速やかに、CCAnimationに渡し、直前のための()ループ内でburpFramesの内容を設定するのですか?CCAnimationが配列をコピーしない場合は、アニメーションの下から空になったばかりです。配列はオートレリースされているので、空にする必要はありません。

同義語はburpParticleFramesです。

スレッドでロック(dictLock)を取得してから、メインスレッドを呼び出すのは不思議そうです。デッドロックを生成するのにぴったりの方法です。メインスレッドがそのスレッドをロックすることを想定していない場合は、複数のバックグラウンドスレッドが実行されていますか?あなたの並行性モデルは何ですか?

[self removeChild:characterSprite cleanup:YES];はおそらくcharacterSpriteをリリースします。うまくいけば、selfのメソッドは通常のココアの慣習に従います。

基本的な保持/解放の問題があるようです。 Read the guideを作成し、ビルドと分析を使用して問題を修正します。あなたのアプリがまだクラッシュした場合は、ゾンビ検出を使用して、割り当て解除後にメッセージが表示されていることを把握します。

+0

ここに問題はありません!私が直面していた問題は何かでした。ちなみに、CCActionを作成してCCCallFuncを使用してスプライト(Xなど)で実行すると、removeChildを呼び出してレイヤーからスプライトを削除しても、実行が@ selectorのメソッド閉じ括弧に当たるまで解放されません。 – Asymptote

+0

あなたは "なぜ前にforループの内容を設定してから、CCAnimationに渡してすぐにRemoveAllObjectsを削除するのですか?CCAnimationが配列をコピーしないと、あなたはただそれを空にしました配列はオートレリースされているので、空にする必要はありません。 なぜccanimationはコピーしません。私は初期化しています。コードに問題はありません.pvr.cczのロードに関するcocos2dのバグがありました。 – Asymptote

+0

"最初の問題は、retainCountを呼び出して、返された数値が意味があると考えていることです。 なぜ意味がありませんか?私の最初のコメントを読んでください。 – Asymptote

関連する問題