Garbage collecting issue with Custom viewbinding i

2019-09-02 18:27发布

问题:

I have a custom calendar control for which there is an custom viewbinding. In this viewbinding we hook up some events which are not decoupled correct and therefor is the garbage collecting not completed. In the following is our custom view binding. As you can see the event is hooked up in the constructor and decoupled in the OnSelectedDate event is triggered(the user selects an date). Therefore if you choose a date the event is decouple correct and garbage collected but if you just go back, the event is still hooked up and no garbage collecting is performed. I thought about trigger the event with null values and and thereby decoulpe the event. But I think there must be some more clever way to achieve this.

namespace CmsApp.Core.Binders
{
    public class CalendarViewBinding:MvxBaseTargetBinding
    {
        private CalendarView _calendarView;
        private DateTime _currentValue;
         public CalendarViewBinding(CalendarView calendarView)
        {
            _calendarView = calendarView;
            _calendarView.OnDateSelected+=OnDateSelected;
        }

         protected override void Dispose(bool isDisposing)
         {
             if(_calendarView!=null)
             {
                 _calendarView.OnDateSelected -= OnDateSelected;
                 _calendarView = null;
             }
             base.Dispose(isDisposing);

         }

        private void OnDateSelected(object sender, SelectedDateEventArgs args)
        {
            _currentValue = args.SelectedDate;
            this.FireValueChanged(_currentValue);
            _calendarView.OnDateSelected -= OnDateSelected;
        }

        public override void SetValue(object value)
        {
            var date = (DateTime)value;
            _currentValue = date;
            _calendarView.SelectedDate = _currentValue;

        }

        public override Type TargetType
        {
            get
            {
                return typeof(DateTime);
            }
        }

        public override MvxBindingMode DefaultMode
        {
            get
            {
                return MvxBindingMode.TwoWay;
            }
        }
    }
}

Any help is appreciated :)

回答1:

It looks to me like your binding is almost correct.

The only issue I can see is that it unsubscribes from the event too often - you can't call _calendarView.OnDateSelected -= OnDateSelected; twice - but I don't think this is the problem you are seeing.

I currently would guess that the problem is not in the code you are using:

  • either there's a bug in the binding code in the underlying framework you are using
  • or something is a bug/issue in the way you are using this binding
  • or your memory leak has nothing to do with this binding

It's not easy to test this from the limited code posted here, but it would be simpler if you could produce a simple app that reproduces the leak you are seeing. Share that and you might be able to get more feedback.


If you believe my guesses are wrong, then the only thing I can suggest is that you switch to WeakReferences inside your binding - but this feels like a sticking plaster rather than a cure.


Just adding a link to when to release objects in mono touch / mvvmcross