处理具有自定义事件的CAKeyFrameAnimation的正确方法是什么?我做了一个测试项目,以最简单的方式展示我正在做的事情。
Here is my Xamarin Studio Project
Here is my XCode Instruments Memory Allocations Trace
要重现我在此内存分配跟踪期间所做的操作,只需运行该项目即可。按绿色按钮10次。 (每按一次绿色按钮,蓝色方块动画) 然后评估内存使用情况。请注意,在我的CreateAnimationEventHandler_Position_AnimationStopped函数中,我正在处理动画。 但是还要注意到,仪器告诉我,我有一些非物体正在泄漏记忆......导致这种情况的原因是什么?我如何正确处理CAKeyFrameAnimations?
我尝试了几种不同的方法来处理它。这是我的结果。按下10个按钮后,我得到大约30-100kb的非物体吸收记忆。我一定做错了什么。
这里有一些要查看的代码(但它也附在项目中):
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;
}
答案 0 :(得分:2)
Xamarin支持的优秀人员为我提供了良好的内存实践资源,并向我展示了非对象并不总是内存泄漏。在这种情况下,他们不是。事实证明,我正确处置。
感谢所有阅读此内容并考虑帮助的人。
http://docs.xamarin.com/guides/cross-platform/application_fundamentals/memory_perf_best_practices/