Странная проблема с блоками и ссылками
Я использую платформу Sparrow (V2), и у меня возникла очень странная проблема, которая может быть связана с Sparrow или с Obj-c. Я использую ARC для проекта.
Я создаю мувиклип, который представляет собой анимацию игры в кости, затем я добавляю к нему слушателя и использую блок для удаления анимации и мувиклипа, как это..
diceAnimationPlayer1 = [self getAnimation:atlasName1 fName:frameName1 nFrames:12];
__weak SPMovieClip *weakMC = diceAnimationPlayer1;
__weak SPSprite *weakSP = villageSprite;
[diceAnimationPlayer1 addEventListenerForType:SP_EVENT_TYPE_COMPLETED block:^(SPEvent *event)
{
[Sparrow.juggler removeObject:weakMC];
[weakSP removeChild:weakMC];
}];
Это все работает отлично. Проблема возникает, если я не хочу удалять мувиклип в этот момент, но хочу удалить diceAnimationPlayer1 позднее, скажем, после завершения другой анимации. Если я попытаюсь сделать
[villageSprite removeChild:diceAnimationPlayer1];
Он не только не удаляет мувиклип, но и заменяет мувиклип на новый Атлас! (У меня есть 6 атласов костей, по одному на каждую сторону), поэтому на последнем кадре кости меняются на новое число.
Я проверил, создаю ли я один мувиклип поверх другого, может быть, там есть 2, но, насколько я вижу, это не так, это очень странно.
У кого-нибудь есть идеи, что может вызвать это? В любом случае, я не совсем понимаю весь этот слабый бизнес. Слабый ориентир как-то создает совершенно новый объект? (хотя проверка переменных в отладке, кажется, показывает, что все они указывают на одно и то же).
Кроме того, добавив к ответу ниже (что, к сожалению, не решает проблему), почему это не удаляет объект?
diceAnimationPlayer1 = [self getAnimation:atlasName1 fName:frameName1 nFrames:12];
__weak __block SPMovieClip *weakMC = diceAnimationPlayer1;
__weak __block SPSprite *weakSP = villageSprite;
[diceAnimationPlayer1 addEventListenerForType:SP_EVENT_TYPE_COMPLETED block:^(SPEvent *event)
{
[Sparrow.juggler removeObject:weakMC];
[villageSprite removeChild:diceAnimationPlayer1];
//[weakSP removeChild:weakMC];
}];
Я получаю тот же результат, анимация игры в кости не удаляется, а просто переключается на другой атлас, показывающий другое окончательное число.
1 ответ
По умолчанию, когда вы ссылаетесь на объект ссылочного типа внутри вашего блока, он сохраняется, для предотвращения его сохранения необходимо пометить его как __block. Попробуйте следующим образом
diceAnimationPlayer1 = [self getAnimation:atlasName1 fName:frameName1 nFrames:12];
__weak __block SPMovieClip *weakMC = diceAnimationPlayer1;
__weak __block SPSprite *weakSP = villageSprite;
[diceAnimationPlayer1 addEventListenerForType:SP_EVENT_TYPE_COMPLETED block:^(SPEvent *event)
{
[Sparrow.juggler removeObject:weakMC];
[weakSP removeChild:weakMC];
}];