正确处理CAKeyFrameAnimation的方法

时间:2014-04-14 18:07:08

标签: ios xamarin.ios instruments dispose cakeyframeanimation

处理具有自定义事件的CAKeyFrameAnimation的正确方法是什么?我做了一个测试项目,以最简单的方式展示我正在做的事情。

Here is my Xamarin Studio Project

Here is my XCode Instruments Memory Allocations Trace

要重现我在此内存分配跟踪期间所做的操作,只需运行该项目即可。按绿色按钮10次。 (每按一次绿色按钮,蓝色方块动画) 然后评估内存使用情况。请注意,在我的CreateAnimationEventHandler_Position_AnimationStopped函数中,我正在处理动画。 但是还要注意到,仪器告诉我,我有一些非物体正在泄漏记忆......导致这种情况的原因是什么?我如何正确处理CAKeyFrameAnimations?

我尝试了几种不同的方法来处理它。这是我的结果。按下10个按钮后,我得到大约30-100kb的非物体吸收记忆。我一定做错了什么。

Without Disposal

With Disposal on animation only not path nor events, more details

With Disposal, more details

这里有一些要查看的代码(但它也附在项目中):

public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        // Perform any additional setup after loading the view, typically from a nib.



        UIImageView ViewToAnimation = new UIImageView(new RectangleF(100, 100, 100, 100));
        ViewToAnimation.BackgroundColor = UIColor.Blue;
        View.AddSubview(ViewToAnimation);



        GoButton = new UIButton(new RectangleF(0, 0, 100, 100));
        GoButton.BackgroundColor = UIColor.Green;
        View.AddSubview(GoButton);
        GoButton.TouchUpInside += delegate {            
            animation = CreateAnimation_Position(ViewToAnimation, new Random().Next(0,500), new Random().Next(0,700), ViewToAnimation.Center.X, ViewToAnimation.Center.Y, 0.4f, CAMediaTimingFunction.FromName (CAMediaTimingFunction.Linear));
            ViewToAnimation.Layer.AddAnimation(animation, "animation");
        };


    }


    public CAKeyFrameAnimation CreateAnimation_Position ( UIView view, float toX, float toY, float fromX, float fromY, float duration_s, CAMediaTimingFunction timingFunction )
    {
        AppDelegate appDel = (AppDelegate)UIApplication.SharedApplication.Delegate;

        CAKeyFrameAnimation positionAnimation = CAKeyFrameAnimation.GetFromKeyPath ("position");
        positionAnimation.Duration = duration_s;
        positionAnimation.TimingFunction = timingFunction;

        PointF toLocation = new PointF(toX, toY);

        // Make a path for this animation
        CGPath path = new CGPath();
        PointF[] lines = {new PointF(fromX, fromY), new PointF(toX, toY)};
        path.AddLines(lines);

        positionAnimation.Path = path;

        event_started = CreateAnimationEventHandler_Position_AnimationStarted(view, toLocation);
        positionAnimation.AnimationStarted += event_started;

        event_stopped = CreateAnimationEventHandler_Position_AnimationStopped(view, positionAnimation);
        positionAnimation.AnimationStopped += event_stopped;

        return positionAnimation;
    }


    public EventHandler CreateAnimationEventHandler_Position_AnimationStarted ( UIView view, PointF toLocation )
    {
        EventHandler animationStartedEvent = delegate {
            // Apply the Position change to the Layer
            view.Layer.Position = toLocation;
        };

        return animationStartedEvent;
    }


    public EventHandler<CAAnimationStateEventArgs> CreateAnimationEventHandler_Position_AnimationStopped ( UIView view, CAKeyFrameAnimation animationToDispose )
    {
        EventHandler<CAAnimationStateEventArgs> animationStoppedEvent = delegate(object sender, CAAnimationStateEventArgs e) {
//              Console.WriteLine("Finished!  finished = " + e.Finished);


//              Console.WriteLine("Removing and Disposing Events");
//              animationToDispose.AnimationStarted -= event_started;
//              animationToDispose.AnimationStopped -= event_stopped;
//              event_started = null;
//              event_stopped = null;
//
//
//              Console.WriteLine("Disposing Animation");
//              animationToDispose.Path.Dispose();


            // For some reason, only calling Dispose on the animation and NOT calling dispose on the Path & events seems to be more efficient... no idea why
            animationToDispose.Dispose();
        };

        return animationStoppedEvent;
    }

1 个答案:

答案 0 :(得分:2)

Xamarin支持的优秀人员为我提供了良好的内存实践资源,并向我展示了非对象并不总是内存泄漏。在这种情况下,他们不是。事实证明,我正确处置。

感谢所有阅读此内容并考虑帮助的人。

http://docs.xamarin.com/guides/cross-platform/application_fundamentals/memory_perf_best_practices/