Кажется, что это проблема с выделением и копированием объектов действий. В этой теме довольно хорошо отвечает на мой вопрос, и этот пост является кратким:
Исходя из моего опыта, вы не можете реально сохранить действия и извлечь из них какую-либо выгоду.
Там действительно нет хорошего способа повторно использовать действия. Если вы обнаружите, что слишком много занимаетесь, что игра нестабильна, вы должны забыть о действиях и просто наметить метод, который выполняет всю работу.
Примеры (Все переменные, заканчивающиеся подчеркиванием, являются переменными класса "variablename _"):
ПЛОХОЙ СПОСОБ ВЫПОЛНИТЬ ДЕЙСТВИЯ:
.... maybe in init
moveAction_ = [[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]retain];
.... Some other function
[sprite1_ runAction:moveAction_];
[sprite2_ runAction:moveAction_];
Этот пример не будет работать, потому что оба sprite1_, sprite2_ скажем, имеют одинаковую позицию.
Они точно не будут двигаться вместе! Это связано с тем, что actionManager ссылается на действие, а вы просто изменили цель этого действия.
Правильный путь:
.... maybe in init
moveAction_ = [[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]retain];
.... Some other function
[sprite1_ runAction:[[moveAction_ copy] autorelease]];
[sprite2_ runAction:[[moveAction_ copy] autorelease]];
Теперь действие будет иметь правильное поведение, но вы по сути потеряли всю эффективность выполнения удержания в первую очередь. Вы в значительной степени создали два новых экземпляра действия.
Код выше точно такой же, как:
[sprite1_ runAction:[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]];
[sprite2_ runAction:[MoveBy actionWithDuration:1.f position:ccp(100.f, 0.f)]];
Так что в итоге вы не получили никакой выгоды от сохранения действия. Так зачем сохранять?
Если вы действительно беспокоитесь о замедлении сделки, то другой способ - потерять удобство действий и создать собственное запланированное действие
...somewhere in init
[self schedule:@selector(moveStuff:)];
// do all you actions manually here
- (void) moveStuff:(ccTick) dt
{
CGPoint delta = ccp(100.f,0.f);
sprite1.position = ccp( (sprite1.position.x + delta.x * dt ),
(sprite1.position.y + delta.y * dt ) );
}
Так что на самом деле вам решать, выбирать ли вам скорость или удобство.