前々から悩んでた、異なるViewController間の変数の共有とか、ゲーム全体で使いたい変数をどのクラス、どのファイルからでも参照できるようにするのに役立ちます。
もちろん一部のViewControllerやクラスのみで使う場合は直接受け渡したほうがいいとも思いますが。
感覚的にはグローバル変数みたいな感じになると思います。
やり方は、まず新しいクラス用にファイルを作ります。NSObjectのサブクラスでいいと思います。
GameData.h
GameData.m
名前は何でもいいです。
まず.hのほうで、共有したいプロパティを宣言します。インスタンス作成のためのuseSharedDataメソッドも、他のクラスが使用することになるので、h.に宣言しておきます。
ここではレベルと位置を保存する変数を作りました。
(GameData.h)
@interface GameData : NSObject
{
}
@property int playerLevel;
@property CGPoint playerLocation;
+(id) useSharedData;
@end
最近は.mのほうに@ synthesize とかいらなくなったみたいです。
次は.mの方で、他のクラスからインスタンスを作るクラスメソッド+(GameData* ) useSharedDataをつくります。いつものallocの代わりに使う用です。
(GameData.m)
@implementation GameData
static GameData* sharedData = nil; //nilで初期化したsharedDataというインスタンスを実装
+(SharedData* ) useSharedData
{
if(sharedData == nil){
sharedData = [[sharedData alloc] init]; //sharedDataがnilなら新しくメモリを確保
}
return sharedData;
}
このメソッドを、他のクラスから、
GameData* sharedData = [GameData useSharedData];
という感じでつかうと、初めての呼び出しのときはallocで新しいメモリが確保されて、2回目以降の呼び出しでは既にあるsharedDataが返されます。
つまり、毎回これさえ呼び出せば、sharedData.playerLocation と sharedData.playerLevel がどのクラスでも同じ変数として使えるということに。
さらに自分は毎回書くのが面倒なので、prefix.pch ファイルのなかに、
#define SHAREDDATA GameData* sharedData = [GameData useSharedData];
という感じにマクロ定義しておきました。
ちなみに、sharedData.playerLocation.x = ~~ と書こうとするとなぜかエラーがでます。なぜか考えてみたんですが、多分最初のドットはplayerLocationに対してのアクセサメソッドの簡略表記、後のドットはxはplayerLocationのインスタンス変数だよという表記で、「sharedData.playerLocation.x =」という書き方ではsharedData.playerLocation.xに対してのセッターになっていないからではないかと(適当)。
まあ表記の問題なので、ポインタ使って
CGPoint* sharedPlayerLocation = sharedData.playerLocation;
sharedPlayerLocation = ~~ ;
とかすればできました。
ちなみにゲッターとしては普通に使えました。
これでいちいち受け渡さなくてもいいし、ゲーム作りがはかどりそう!
2015/12 追記
練習で作っていたアプリを遊べるように改良してリリースしてみました!よかったら遊んでみてください。
DodgingRabbit
関連書籍
関連書籍
cocos2dで作る iPhone&iPadゲームプログラミング
posted with amazlet at 12.09.29
Steffen Itterheim
インプレスジャパン
売り上げランキング: 24615
インプレスジャパン
売り上げランキング: 24615


