Xamarin表单 - iOS自定义渲染器 - 处置观察者

时间:2017-07-15 15:51:57

标签: xamarin.ios xamarin.forms

当对正在定制的ListView的网页提出异议时,以下内容会崩溃。错误说我的观察员没有被处理掉。

public class ChatListViewRenderer : ListViewRenderer
{
    private IDisposable _onContentSizeChangedObserver;
    private IDisposable _onFrameChangedObserver;

    protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
    {
        base.OnElementChanged(e);
        if (Control == null) return;

         _onContentSizeChangedObserver = Control.AddObserver(new NSString("contentSize"), NSKeyValueObservingOptions.OldNew, OnContentSizeChanged);
        _onFrameChangedObserver = Control.AddObserver(new NSString("frame"), NSKeyValueObservingOptions.OldNew, OnFrameChanged);
    }


    protected override void Dispose(bool disposing)
    {
        _onContentSizeChangedObserver.Dispose();
        _onFrameChangedObserver.Dispose();
        base.Dispose(disposing);
    }
}

更新

我在包含ViewWillDisapear的网页PageRenderer的{​​{1}}内进行了尝试,但问题仍然存在。

ListView

2 个答案:

答案 0 :(得分:1)

OnElementChanged被调用两次 - 创建控件然后处理时。

if(e.NewElement != null)
      addobserver and do other stuff
if(e.oldElement!=null)
       remove observer and destroy everything you allocated

答案 1 :(得分:0)

一个更“直观”的例子:

private IDisposable _onAppOrientationChangedObserver;

protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
   base.OnElementChanged (e);

   if (e.OldElement != null)
   {
      _onAppOrientationChangedObserver?.Dispose();
   }

   if (e.NewElement != null) 
   {
      if (Control!=null)
      {
            _onAppOrientationChangedObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIDevice.OrientationDidChangeNotification, (obj) =>
            {
              _uiOrientation = UIApplication.SharedApplication.StatusBarOrientation;
              _deviceOrientation = UIDevice.CurrentDevice.Orientation;
            });
      }
   }

}