简体   繁体   中英

How to clean up a UIViewController in Xamarin.iOS?

Consider we have a custom UIViewContoller.

Now we have to make some clean up on UIViewController unload. For example, if we use UIWebView as a subview in our view controller, it's recommended to set its delegate to null and call StopLoading() method on unload.

Some sources say it's not recommended to make clean up overriding Dispose() method, because it concerns only managed object lifecycle.

Other sources say it's not recommended to use ViewDidDissappear() for these purposes because it can be called twice.

How to handle it right?

ViewDidDisappear() and ViewWillDisappear() will not be called multiple times; at least not without a balanced call to ViewDidAppear() and ViewWillAppear() . If you see more calls to the disappear methods than to the appear methods, you have a bug in your code. If you want to make sure, your cleanup happens only once (for sanity), but isn't the solution something as simple as this:

bool myCleanupIsDone = false;

public override void ViewDidDisappear()
{
  if(myCleanupIsDone)
  {
    return;
  }

  myCleanupIsDone = true;
  CleanUpWhateverNeedsToBeCleanedUp();
}

You should almost never need to override Dispose() unless you are dealing with unmanaged resources. Xamarin.iOS does that a lot internally but for your code and in your case it is not relevant.

Normally you would create your required objects in ViewWillAppear() and clean them up in the disappear methods. That way you would not need to check if something has already been cleaned up.

ViewWillDisappear and ViewDidDisappear can actually be called multiple times, on iPhone for example every time when a new controller is presented or pushed. But I think it's still the right place to do all the necessary cleanups.

Krumelur's proposal would end in a null delegate of your UIWebView once your controller has been disappeared for the first time – if the user comes back, it would probably crash.

So instead of setting a flag you could check, if the controller you want to clean up is beeing popped or dismissed – if that's the case, you can safely do all the work.

Here's some code I found in one of my projects (seems I've been through this before ;)):

public override void ViewDidDisappear(bool animated)
{
          if ((NavigationController == null && IsMovingFromParentViewController) ||
              (ParentViewController != null && ParentViewController.IsBeingDismissed))
          {
              CleanUpAfterDisappearing();
          }

          base.ViewDidDisappear(animated);
}

也许您只需在操作系统通过覆盖自定义视图控制器中的DidReceiveMemoryWarning()方法指示应用程序执行此操作时清理资源: http ://iosapi.xamarin.com/index.aspx?link = M%3AMonoTouch.UIKit .UIViewController.DidReceiveMemoryWarning

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM