【问题标题】:Should I removeBehavior a UIPushBehavior -- I am adding many pushes我应该删除行为一个 UIPushBehavior - 我添加了许多推送
【发布时间】:2014-09-03 14:23:48
【问题描述】:

我有一个小 UIView,它在一个盒子里弹跳。我正在添加 Instantaneous 模式。推。事实上,我添加了很多推动力——5 赫兹或更多赫兹。

谜底:

(1) 如果需要,我是否必须 removeBehavior?? .. 何时?!? “之后”是“瞬间”?

(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];
    }

{注意:我只是简单地分配 UIPushBehavior 每次我需要一个。请注意,如果您尝试使用“just one”作为属性,它不起作用。事实上,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];
        }
    }

【问题讨论】:

    标签: ios uikit-dynamics uidynamicbehavior


    【解决方案1】:

    回答您的问题:

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

    2. 从技术上讲,您不必调用removeBehavior 进行瞬时推送,因为一旦瞬时推送发生,该行为的active 状态就会关闭。

      话虽如此,我还是倾向于删除该行为,因为否则会占用内存,而动画师会强烈引用这些非active 瞬时推送行为。 (这很容易通过记录动画师的behaviors 属性来验证,该属性是它正在跟踪的所有行为的数组。)最终可能会出现与性能相关的问题,它会遍历所有这些非@987654326 @ 行为也是如此,尽管我怀疑内存问题可能更重要。

      但与保持active 的其他行为(例如UISnapBehavior)不同,您不必担心挥之不去的瞬时推送行为会继续影响添加它的项目。

    3. 它们不会“过期”,本身,但是,是的,它们很快就会进入active 状态NO

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

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

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

    或者,您可以设置一个 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];
    

    【讨论】:

    • 谢谢!我必须做一些测试,看看何时可以删除该行为:该行为是否在该行代码“然后”发生?或者,仅在例程结束时(或者更像是帧驱动的游戏引擎)。我会发现...
    • 动画师不会执行这些行为,直到您将主线程返回给运行循环(即您的例程退出)。所以,确保你永远不会阻塞主线程。 (这是一般规则,因此请确保您避免在任何时候阻塞主线程,否则您将对动画师执行动画的能力产生不利影响。)但是您必须等待动画师接听的事实这种行为是为什么您不只是立即删除该行为,而是异步删除它(即在一段时间后,或者更好,当调用 action 块时)。
    • 啊,好吧,你已经回答了这个问题 - 太棒了!
    • PS .action 的想法.. 令人难以置信。
    • 我这个周末要去旅行,所以我不确定在下周回来之前我是否有机会看看,但我会尽量抽出几分钟...
    猜你喜欢
    • 2019-11-30
    • 2012-11-16
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多