removeChildByTag で EXC_BAD_ACCESS が発生する

cocos2dにて、CCMenu を何度か追加・消去するプログラムを作成していたところ、
EXC_BAD_ACCESS が発生しました。

具体的には、CCMenuItem が3つ入った CCMenu を構築したあと、
メニューアイテム・メニュー全てを removeChildByTag できれいに削除しようとしました。

CCNode* menuanswers = [self getChildByTag:kTagAnswers];
[menuanswers removeChildByTag:kTagAnswer1 cleanup:YES];
[menuanswers removeChildByTag:kTagAnswer2 cleanup:YES];
[menuanswers removeChildByTag:kTagAnswer3 cleanup:YES];
[self removeChildByTag:kTagAnswers cleanup:YES];

最後の行で EXC_BAD_ACCESS が発生。
発生したのは、CCMenu -onExit にて以下の[selectedItem_ unselected]の部分。

- (void) onExit
{
	if(state_ == kCCMenuStateTrackingTouch)
	{
		[selectedItem_ unselected];
		state_ = kCCMenuStateWaiting;
		selectedItem_ = nil;
	}
	[super onExit];
}

CCMenu は、CCMenuItem が最後まで生きていることを前提にしているようなので、
CCMenu のみを削除することで対応しました。

NSKeyedArchiverでデータをファイルへ保存する

iOSでデータを永続化しファイルへ保存するには、いくつか方法があるようです。ここではNSKeyedArchiverを使った方法をご紹介します。

以下のメソッドは、3つの変数を受け取り、ファイル保存までを行います。

- (void)saveToFileWithVar1:(id)var1 var2:(id)var2 var3:(id)var3
{
    NSMutableDictionary* dicToSave = [[NSMutableDictionary alloc] init];

    NSMutableArray* arrayVals = [[NSMutableArray alloc] init];
    [arrayVals addObject:[[NSDictionary alloc] initWithObjectsAndKeys:
                  var1,@"var1",var2,@"var2",var3,@"var3", nil]];
    // add to dictionary
    [dicToSave setValue:arrayVars forKey:@"vars"];

    NSNumber* value;
    // add numbers
    value = [NSNumber numberWithDouble:1.0f];
    [dicToSave setValue:value forKey:@"value1"];
    value = [NSNumber numberWithDouble:3.5f];
    [dicToSave setValue:value forKey:@"value2"];

    // save to file
    [NSKeyedArchiver archiveRootObject:dicToSave toFile:@"/path/to/file"];
    [dicToSave release];
}

ファイルに保存するのは1オブジェクトです。従って、ここでは辞書オブジェクト dicToSave の内容をファイルに保存します(N行目)。

つまり、dicToSave辞書に、保存したいデータを放り込んで行けばよいわけです。この例では、配列1つ(キーはvars)と数値2つ(キーはvalue1、value2)を放り込んでいます。

NSMutableArrayなどの配列へ、プリミティブ型を格納できないことには注意しましょう。