Cocos2d-xでCCObjectのコピーをする際の注意(メモリリーク)

Pocket

cocos2dx

cocos2d-xには2.xではCCCopyingがcopy()というメソッドを持っていて(3.xではClonableが持ってるのかな?)、結構便利なので主にアニメーション関連で使ったりしてたんですが、使い方を誤るとメモリリークしちゃうので忘備も兼ねてかいておきます。

copyメソッドに関して


まずはいつも通り、cocos2d-xのcopy()メソッドについての紹介です。
cocos2d-xの3.x系ではよくわからないのですが、2.x系では殆どのオブジェクトがCCObjectを継承していて、そのCCObjectはCCCopyingというインターフェイスを継承しています。

この、CCCopyingは「copyWithZone()」メソッドを持ってるだけのインターフェイスなのですが、これは「オブジェクトをクローンする為の処理」を記述する場所で、CCObjectのcopy()メソッドが呼ばれる際にこのメソッドが呼ばれて、ごにょごにょとインスタンスをクローンします。

まあ、単に新しいオブジェクトを生成し、そのメンバ変数やらに自信のメンバ変数の値を入れていく、というようなことを記述するわけですが。

要するにそれがあるからインスタンスをコピーできるよってことですね。
コピーするためにはそういう記述をしないといけなくて、それがちょっと面倒なのですが、CCAction系は大抵全部ちゃんと実装してるんで同じようなアクションをさせたい時なんかに使うとそれなりに便利だったりします。

たとえばCCMoveByで「右に100px移動させ、次に左に100px移動させ、また右に100px移動させたい」場合、以下のように記述できます。

CCMoveBy* move = CCMoveBy::create(1.0f , ccp(100,0));
CCSequence* seq = CCSequence::create(move , move->reverse() , (CCMoveBy*)move->copy() , NULL);
sprite->runAction(seq);

reverse()は、設定したアクションの反対のことをさせることができます。
実質ひとつの値を設定するだけで3つのアクションを設定できるんで、結構便利っちゃ便利です。

でもこれ、メモりリークします


実際ぼくが間違えてつかっちゃって、メモリリークしてました(´・ω・`)

基本copy()が呼び出された場合メンバ変数の値が同じインスタンスが新しく生成されるのですが、
どれもautorelease()がされていません

というわけで以下のようにこちらで明示的に呼び出す必要があります。

CCMoveBy* move = CCMoveBy::create(1.0f , ccp(100,0));
CCSequence* seq = CCSequence::create(move , move->reverse() , (CCMoveBy*)move->copy()->autorelease() , NULL);
sprite->runAction(seq);

autorelease()は、実はメソッドチェーンになってて戻り値で自身(CCObject*)を返します。
というわけで、こういう書き方でOKです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です