読者です 読者をやめる 読者になる 読者になる

夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【Objective-C, cocos2d】Weakのインスタンス変数についての疑問解決しました

Objective-C cocos2d

前回悩んでいたweak指定のインスタンス変数にオブジェクトを入れるにはどうすれば良いかという疑問が解決しました。

__weak CCSprite* testと言うインスタンス変数があったとして、

_test = [[CCSprite alloc] initWithFile@"test-sprite.png"];
[self addChild:_test];

とやろうとすると、

"Assigning retained object to weak variable; object will be released after assignment"

という警告がでて、すぐにオブジェクトが解放され、addChildできないという問題があり、

_test = [[CCSprite spriteWithFile@"test-sprite.png"];
[self addChild:_test];

とすれば大丈夫な気もするものの、必ずしも意図した動作しないかもしれないという情報をとあるフォーラムで見て、どうした物かと考えていました。

が、「いったんローカル変数に入れてやれば良い」という単純な答えに気がつきました。ローカル変数に入れておけばそのスコープ内でオブジェクトが解放される事はないのでその間にaddChildするなりweak指定のインスタンス変数に入れてやれば意図した通りに動作するはずです。コードにすると、

CCSprite* temp = [[CCSprite alloc] initWithFile@"test-sprite.png"];
[self addChild: temp:
_test = temp;

となります。
これで安心してweakのインスタンス変数やプロパティをつかえます。勉強になりました。

今、あたり判定を実装しているのですが、今の構造だと相当無理がある事に気がつきました。CCNodeのuserObjectにオブジェクト本体へのポインタを入れたりプロトコルを使って衝突した事を知らせてもらうメソッドを実装したりしましたが、複雑になり過ぎた気がします。ここで方向転換し、CCSpriteをサブクラスを作ってシンプルに実装したいと思います。「CCSpriteを継承して自分のクラスを作るのは美しくない」とやたらこだわっていたLearn Cocos2d 2: Game Development for Iosの著者も、結局後の方の章では「簡潔さとスプライトバッチングのためCCSpriteを継承してクラスを作る」などとやっているので、なんだかんだ言って、やっぱりそうなるのかという感じです。
では、次回はプログラムをガッツリ書き換えて当たり判定を実装したいと思います。