[cocos2d-x] CCArray と CCMutableArray についてのメモ

cocos2d for iPhoneと違う点があるのでちょっと分かりにくい。。


CCArrayの中身を走査する

CCArray の中身を走査したい時は CCARRAY_FOREACH(__array__, __object__) マクロを使用する。
CCNode#childrenメソッドはCCArrayで子オブジェクトを返すので CCARRAY_FOREACH で走査できる。

CCNode *parent = CCNode::node();
CCNode *child01 = CCNode::node();
child01->setTag(777);
CCNode *child02 = CCNode::node();
child02->setTag(666);

parent->addChild(child01);
parent->addChild(child02);

CCArray *childs = parent->getChildren();

CCObject *aChild = NULL;
CCARRAY_FOREACH( childs, aChild ) {
  CCLog("Tag Number is %d", ((CCNode*)aChild)->getTag());
}

CCArrayのヘッダーと各種関数

以下はソースコードのコピペに一部自分でコメントを加えたもの。
名前を見ればほぼ意味が分かるものばかり。

class CC_DLL CCArray : public CCObject
{
public:
  ~CCArray();
  static CCArray* array();
  static CCArray* arrayWithCapacity(unsigned int capacity);
  static CCArray* arrayWithArray(CCArray* otherArray);

  bool init();
  bool initWithCapacity(unsigned int capacity);
  bool initWithArray(CCArray* otherArray);

  // Querying an Array
  unsigned int count();
  unsigned int capacity();
  unsigned int indexOfObject(CCObject* object);
  CCObject* objectAtIndex(unsigned int index);
  CCObject* lastObject();
  CCObject* randomObject(); // コレクションのうちからランダムに1つ返す
  bool containsObject(CCObject* object); // 引数のオブジェクトが存在すれば true を返す

  // Adding Objects
  void addObject(CCObject* object);
  void addObjectsFromArray(CCArray* otherArray);
  void insertObject(CCObject* object, unsigned int index);

  // Removing Objects
  void removeLastObject();
  void removeObject(CCObject* object);
  void removeObjectAtIndex(unsigned int index);
  void removeObjectsInArray(CCArray* otherArray);
  void removeAllObjects();
  void fastRemoveObject(CCObject* object); // こちらの方が速度が早いけども、オブジェクトの並び順が変化するので、objectAtIndex を使ったりしてオブジェクトを取り出したい場合などに使用すると困ったことになる。(削除した部分に、最後のオブジェクトを移すことで削除を実現しているため並び順が変化する。removeObjectの場合は 削除後に memmove でデータを詰めているので並び順が変化しないが、memmoveの処理が入るのでfastRemoveより低速)
  void fastRemoveObjectAtIndex(unsigned int index); // なので fastRemoveを使う配列は、中身のオブジェクトの順番がぐちゃぐちゃに変化しても問題ない場合(CCARRAY_FOREACHなどで全てのオブジェクトに対して処理を実行する場合やTag値によってオブジェクトを取得する場合などはOK。特定のインデックスに特定のオブジェクトが存在すると想定して使用する場合はダメ)にしか使ってはいけない。当然、fastRemoveを使った場合 exchangeObject や reverseObject はたぶん使えなくなる。

  // Rearranging Content
  void exchangeObject(CCObject* object1, CCObject* object2);
  void exchangeObjectAtIndex(unsigned int index1, unsigned int index2);
  void reverseObjects();
  void reduceMemoryFootprint(); // オブジェクトを削除した後などに、メモリの割当を縮めることができる。(reallocする)

public:
  ccArray* data;

private:
	CCArray() : data(NULL) {};
};

CCArrayは cocos2d for iPhone だと NSArray よりちょっぴり高速らしいけど、cocos2d-x だとどうなんだろうね。std::vector より早いんだろか。

CCMutableArray と CCArray

CCMutableArray はテンプレートで保持する型を指定して使用する可変配列である。
CCMutableArray なんてクラスがあるのでCCArrayは可変配列ではないように思えるけど CCArrayも可変配列なので間違えないように。

CCMutableArray は cocos2d for iPhone には存在しないクラスであり、std::vector のラッパーです。で、内部のstd::vectorを操作するためのメソッドが用意されている(CCArrayでは CCObject** 変数で配列を管理している)。vector を cocos2d for iPhone 風にしたクラス?ごめんうまく説明できない。まぁCCObjectを継承していて autorelease なんかでメモリ管理が楽なので 動的に配列を作る場合はこいつを使うといいかもねって感じだと思う。

また、CCArray は cocos2d for iPhone ではオブジェクトであればなんでも格納できたのだけど、cocos2d-xではCCObjectおよびそのサブクラスしか格納できないので注意すること。CCObject以外を配列にしたい場合は list なり CCMutableArray なり使えばOK。

  1. ※バージョン2移行は CCMutableArray, CCMutableDictionary は非推奨となり CCArray, CCDictionary を使うべき

  1. トラックバックはまだありません。

*


Advertisement