我应该删除行为UIPushBehavior - 我正在添加许多推送

Fat*_*tie 2 ios uidynamicbehavior uikit-dynamics

我有一个小UIView在一个盒子里反弹.我正在添加一个瞬时模式.推.事实上,我正在添加很多推 - 5或更多Hz.

神秘:

(1)我必须删除行为???? 如果是的话...... 什么时候?!?"后"是"瞬间"?

(2)UIPushBehaviorModeInstantaneous是一个特例,你不必(或不能)删除那些??

(3)当你添加行为时:那个......保留吗?!UIPushBehavior?要么??WTF?

(4)我似乎无法在任何地方找到这些方面!

-(void)pushMeRight:(CGFloat)mag
    {
    if ( self.bounceAnimator == nil ) return;
    NSLog(@"...........push me right %.2f", mag);

    UIPushBehavior *pushRight = [[UIPushBehavior alloc]
            initWithItems:@[self]
            mode:UIPushBehaviorModeInstantaneous];

    pushRight.magnitude = mag;
    pushRight.angle = radians(0);   // (NB, 0 is right, 90 is down)
    [self.bounceAnimator addBehavior:pushRight];
    }
Run Code Online (Sandbox Code Playgroud)

{注意:我每次需要时都会分配UIPushBehavior .请注意,如果您尝试使用"只有一个"作为属性,则它不起作用.事实上,Rob在下面解释了原因.}


经过极其广泛的测试,我们发现Rob的"第二"解决方案,使用.action,基本上是完美的.

经过大量测试后,我们强烈建议以下代码,实际上是"解决方案",是重复推送代码的唯一方法.感谢Rob的好处:/

-(void)pushAllUp:(CGFloat)mag
    {
    if ( self.bounceAnimator == nil ) return;
    for ( UIView *pushme in self.subviews )
        {
        UIPushBehavior *pp =
        [[UIPushBehavior alloc]initWithItems:@[ pushme ]
             mode:UIPushBehaviorModeInstantaneous];

        pp.magnitude = mag;
        pp.angle = radians(270); // (NB, 0 is right, 90 is down)

        UIPushBehavior __weak *weakPP = pp;
        pp.action = ^{ if (!weakPP.active)
             [self.bounceAnimator removeBehavior:weakPP];};

        [self.bounceAnimator addBehavior:pp];
        }
    }
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 6

在回答你的问题时:

  1. 是的,你UIPushBehavior正确地添加了.

  2. 从技术上讲,您不必removeBehavior立即进行推送,因为一旦发生瞬时推送,行为将active立即关闭.

    话虽如此,我倾向于消除这种行为,因为你正在以其他方式占用记忆,动画师保持对这些非active瞬时推动行为的强烈参考.(这可以通过记录动画师的behaviors属性来轻松验证,该属性是它正在跟踪的所有行为的数组.)最终可能会出现与性能相关的问题,即迭代所有这些非active行为,尽管我怀疑内存问题可能更为重要.

    但与其他行为(例如UISnapBehavior)不同active,您不必担心延迟的瞬时推送行为会继续影响其添加的项目.

  3. 他们本身并没有"过期",但是,是的,他们很快就会进入active状态NO.

  4. 是的,当您向动画师添加行为时,动画师将保留对它的强引用,直到您删除该行为.

就个人而言,我倾向于在添加后删除该行为.因为它是瞬间的,它的移除时间并不是非常关键,你可以做一些简单的事情:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [self.animator removeBehavior:push];
});
Run Code Online (Sandbox Code Playgroud)

或者,您可以设置一个action为您删除它.

UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:self.items mode:UIPushBehaviorModeInstantaneous];
push.pushDirection = ...

UIPushBehavior __weak *weakPush = push;  // avoid strong reference cycle
push.action = ^{
    if (!weakPush.active) {
        [self.animator removeBehavior:weakPush];
    }
};

[self.animator addBehavior:push];
Run Code Online (Sandbox Code Playgroud)