Proper way to dispose/cleanup memory in a UIPageViewController ?

ConnorFlaatConnorFlaat USMember

I have a UIPageViewController with a possibly infinite number of controllers in it for looking at images in a gallery type fashion. Disposing of these images is of course very important to avoid infinite memory growth.

Upon testing it looks like my custom view controllers that are used in my UIPageViewControllerDataSource are never getting their dispose method called, only ViewDidDisappear.

What is the proper way to dispose/cleanup memory in this case?

So far my options seem to be:

  1. Use the GetPreviousViewController/GetNextViewController methods to dispose of the reference view controller.

  2. Call Dispose in ViewDidDisappear for my view controllers.

  3. Interact with ViewControllers or ChildViewControllers and dispose of some in FinishedAnimating

None of these seem exactly perfect. Am I missing something?

Answers

  • ConnorFlaatConnorFlaat USMember

    At the end of FinishedAnimating I ended up adding the following:

    //Cleanup non adjacent controllers
    var childControllers = ChildViewControllers;
    foreach (BaseMediaItemController childController in childControllers)
    if (childController.Index < (CurrentIndex - 1) || childController.Index > (CurrentIndex + 1))
    childController.Dispose ();

  • Greg767Greg767 CHMember ✭✭

    @ConnorFlaat
    Hi,
    When I subclass an UIPageViewController there is no FinishedAnimating method..
    Are you sure about the method name?
    In my case even if I call Dispose on the child UIViewControllers memory is still not freed. I am starting to run out of ideas.

  • ConnorFlaat.1662ConnorFlaat.1662 USMember ✭✭

    It's an event.. sorry for the confusion! In my constructor I simply did DidFinishAnimating += FinishedAnimating; where FinishedAnimating is your event handler.

  • Greg767Greg767 CHMember ✭✭

    @ConnorFlaat.1662
    Okay thanks.
    And when you do that do your UIViewController's ViewDidUnload method gets called? Because at the moment no matter how I call Dispose on the childs, they seem to stay in memory since I start receiving memory warning and then it crashes.

    Also do you use the DataSource way of doing things or only the SetViewcontrollers and the GetPreviousViewController/GetNextViewController methods?

  • ConnorFlaat.1662ConnorFlaat.1662 USMember ✭✭
    edited June 2015

    @Greg767 I'm not sure about ViewDidUnload. I have my memory cleanup in Dispose and that is called.

    I use both PageViewDataSource and SetViewControllers.

    I also overrode SetViewControllers to do:

    public override void SetViewControllers (UIViewController[] viewControllers, UIPageViewControllerNavigationDirection direction, bool animated, UICompletionHandler completionHandler)
    {
        //Each time SetViewControllers is called we want to make sure we dispose of any previous controllers
        var childControllers = ChildViewControllers;
        foreach (var child in childControllers)
            child.Dispose ();
    
        base.SetViewControllers (viewControllers, direction, animated, completionHandler);
    }
    

    Since I call it as a way to sort of ReloadData and need to make sure things are disposed before the new controllers are set.

  • Greg767Greg767 CHMember ✭✭

    @ConnorFlaat.1662
    OK, well I will implement PageViewDataSource to see if that changes anything.
    When I tried to override the SetViewControllers as you did, at the beginning of the page turn animation it clears out the current pages and it is not giving a nice effect since pages just disappear before the animation.
    Didn't you have that problem?

  • ConnorFlaat.1662ConnorFlaat.1662 USMember ✭✭
    edited June 2015

    Why would SetViewControllers be called on the page turn animation? That is where GetPreviousViewController and GetNextViewController from the PageViewDataSource are supposed to return a controller. I'm not using page curl by the way.

  • Greg767Greg767 CHMember ✭✭

    Oh I forgot to tell that I have left and right pager arrows and they do use it to set the pages...
    Is there another way to do arrow paging without calling the SetViewControllers method?

  • ConnorFlaat.1662ConnorFlaat.1662 USMember ✭✭

    I have arrow paging too.

    My code is:

    if (index >=MediaItems.Count || index < 0)
                    return;
    
    var controller = _dataSource.GetControllerForIndex (index);
    
    SetViewControllers (new [] { controller },
            UIPageViewControllerNavigationDirection.Forward,
            false, null);
    
  • Greg767Greg767 CHMember ✭✭
    edited June 2015

    Thanks for these snippets and the quick responses, I have the feeling that I am doing it wrong.
    I am going to implement the data source as it should be and hopefully that will solve my problems.

Sign In or Register to comment.