Disposing and dealing with events on dynamically instantiated views

If I create a view, such as a toolbar, in ViewDidLoad of my ViewController dynamically and add it to the page, storing the toolbar as a private variable - do I need to do anything special to have it disposed of properly (will it prevent my ViewController from getting cleaned up if the user clicks back etc.)? I would think in OnDispose I can check for null, call Dispose on the toolbar and null it out - but is that too late (will it keep my parent ViewController in memory)?

Also, I understand how you should subscribe and unsubscribe from event handlers in ViewWillAppear and ViewWillDisappear, if I create a UIView subclass (a custom control) in ViewDidLoad and add it as a subview of my ViewController, and it in turn dynamically instantiates child views that are hooked up via subscriptions (button.Click += handler etc.) do these also need to have their event handlers added and removed when the custom UIView subclass appears and disappears for cleanup to happen properly?

Thanks.

Tagged:

Posts

  • BerayBentesenBerayBentesen TRUniversity ✭✭✭✭

    Use lambda for click event instead of delegates for example :

    button.Click += (sender, e) => { ... }

    Also work with using statements for disposable objects.

    Check documentation here

  • JaymeEdwardsJaymeEdwards USMember ✭✭
    edited November 2016

    The lambdas don't allow your ViewController to be disposed from what I've read on StackOverflow - it being better to explicitly subscribe and unsubscribe in ViewWillAppear and ViewWillDisappear? But the documentation doesn't talk about ViewController's specifically: https://developer.xamarin.com/guides/cross-platform/deployment,_testing,_and_metrics/memory_perf_best_practices/#events

    I am using using statements when I use a variable that is only in method scope, but I'm referring to the case where I instantiate a UIView, such as a toolbar, in ViewDidLoad and add it to my subviews, but it is also stored as a private variable since it is used elsewhere in the class.

  • BerayBentesenBerayBentesen TRUniversity ✭✭✭✭

    Here is a post that talked a lot about events for Xamarin iOS, I did not notice any problem because of lambda or delegate or even Toolbar. Also here, another topic about your question that may help more.

  • JaymeEdwardsJaymeEdwards USMember ✭✭
    edited November 2016

    Here's an example. Assume this ViewController is segued to from another ViewController within a NavigationController. If I don't make sure the event is gone in ViewWillDisappear, when clicking back on the device the ViewController is not disposed. If I do, I can see Dispose getting called.

    public class MyViewController : UIViewController
    {
      UIViewCustomSubclass _someView;
    
      public MyViewController(IntPtr handle) : base (handle) {}
    
      public override void ViewDidLoad() {
        base.ViewDidLoad();
    
        // Store the new view and add it as a subview
        _someView = new UIViewCustomSubclass(...
        View.AddSubview(_someView);
      }
    
      void MyHandler() {
        // Doesn't really matter, we just use the view somewhere else -
        // the only reason it's being stored as a private variable
        _someView.DoSomethingWithView();
      }
    
      public override void ViewWillAppear(bool animated)
      {
        base.ViewWillAppear(animated);
        _someView.SomeEvent += MyHandler;
      }
    
      public override void ViewWillDisappear(bool animated)
      {
        // If I don't unsubscribe here (and do it in dispose instead)
        // when the user clicks "back" my ViewController disappears 
        // but dispose is never called...
        _someView.SomeEvent -= MyHandler;
        base.ViewDidAppear(animated);
      }
    
      public override void Dispose(bool disposing)
      {
        if (disposing)
        {
          if (_someView != null)
          {
            // I can dispose the custom view here, but 
            // I can't remove it as a subview since the view
            // hierarchy is gone. When is Xamarin removing 
            // _someView from its superview?
            _someView.Dispose();
            _someView = null;
          }
        }
    
        base.Dispose(disposing);
      }
    }
    
Sign In or Register to comment.