2014-04-14 6 views
0

사용자 지정 이벤트가있는 CAKeyFrameAnimation을 처리하는 적절한 방법은 무엇입니까? 나는 가능한 한 가장 단순한 방법으로 정확히 무엇을하고 있는지를 보여주는 테스트 프로젝트를 만들었다. Here is my XCode Instruments Memory Allocations TraceCAKeyFrameAnimation을 적절하게 처리하는 방법

Here is my Xamarin Studio Project

은 단순히 프로젝트를 실행,이 메모리 할당 추적하는 동안 내가 한 일을 재현합니다. 녹색 버튼을 10 번 누릅니다. 녹색 버튼을 누를 때마다 파란색 정사각형이 움직입니다.
그런 다음 메모리 사용량을 계산하십시오. 내 CreateAnimationEventHandler_Position_AnimationStopped 함수에서 애니메이션을 삭제합니다. 또한 인스 트루먼 트가 메모리가 새지 않는 비 오브젝트가 많다고 말하고 있습니다 ... 그 원인은 무엇입니까? CAKeyFrameAnimations를 올바르게 처리하려면 어떻게해야합니까?

나는 그것을 처분하는 몇 가지 다른 방법을 시도했다. 여기 내 결과가 있습니다. 단지 10 번의 버튼 누름 후에 약 30-100kb의 비 객체 흡수 메모리를 얻습니다. 나는 틀린 일을해야만합니다. 여기

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

With Disposal, more details

그리고

Without Disposal

는보고 몇 가지 코드입니다 (하지만 첨부 된 프로젝트도의) : 자 마린 지원에

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

답변

2

위대한 사람들이 준 나에게 좋은 기억 실천에 관한 좋은 자료들을 보여주고, 비 - 물체가 항상 기억이 아니라는 것을 보여 주었다. 누출. 이 경우에는 그렇지 않습니다. 그래서 내가 올바르게 처분한다는 것이 밝혀졌습니다.

이 내용을 읽고 도움을 주신 모든 분들께 감사드립니다.

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