Lambda 无法在 cocos2d 中复制 Spawn 和 Actions?

Lambda couldn’t copy Spawn and Actions in cocos2d?

我正在尝试 运行 lambda 中的 Spawn 和 Scale 操作,但 Lambda 根本不复制它们的值。在下面的代码中,我定义了一个 onSelectedSpawn,它是一个 Spawn。 mSettingmFamilyTV 是 MenuItemImage。我做错了什么?非常感谢您的帮助。

auto fadeIn = FadeTo::create(0.5f, 255);
auto scaleIn = ScaleBy::create(0.5f, 1.4f);
auto onSelectedSpawn = Spawn::createWithTwoActions(fadeIn, scaleIn);

// This run without any problem
mSetting->runAction(onSelectedSpawn); 
mFamilyTV = MenuItemImage::create("en_block5.png", "en_block5_hover.png",
        [=](cocos2d::Ref* pSender){

      //Running Spawn makes app crashed because the lambda couldn't copy onSelectedSpawn's value
    mFamilyTV->runAction(onSelectedSpawn);
      //Running Scale action make app crashed too. It also doesn't copy scaleIn at all
        mFamilyTV->runAction(scaleIn);
});

为了在 lambda 中使用局部变量,您已经显式传递了它。另外你必须保留动画,因为它们会从内存中释放。

auto fadeIn = FadeTo::create(0.5f, 255);
auto scaleIn = ScaleBy::create(0.5f, 1.4f);
scaleIn->retain();
auto onSelectedSpawn = Spawn::createWithTwoActions(fadeIn, scaleIn);
onSelectedSpawn->retain();

// This run without any problem
mSetting->runAction(onSelectedSpawn); 
mFamilyTV = MenuItemImage::create("en_block5.png", "en_block5_hover.png",
        [&, scaleIn, onSelectedSpawn](cocos2d::Ref* pSender){

        //this will only work once, next time you have to clone action
        mFamilyTV->runAction(onSelectedSpawn->clone());
        mFamilyTV->runAction(scaleIn->clone());
});

//somewhere where you no longer need these animations, for example when leaving a scene:
scaleIn->release();
onSelectedSpawn->release();

我认为这个解决方案有点太痛苦了,因为你必须将动作传递给 lambda 并记住 retain/release 和克隆。 最简单的方法是创建特殊函数,在适当的位置创建这些动画:

mFamilyTV = MenuItemImage::create("en_block5.png", "en_block5_hover.png",
        [&](cocos2d::Ref* pSender){

        mFamilyTV->runAction(createOnSelectedSpawn());
        mFamilyTV->runAction(createScaleIn());
});

ActionInterval* HelloWorld::createScaleIn(){
    return ScaleBy::create(0.5f, 1.4f);
}

ActionInterval* HelloWorld::createOnSelectedSpawn(){
    auto fadeIn = FadeTo::create(0.5f, 255);
    auto scaleIn = createScaleIn();
    return Spawn::createWithTwoActions(fadeIn, scaleIn);
}