user2117204
user2117204

Reputation:

Unloading viewControllers from UIPageViewController

I got a UIPageViewController where I add other viewControllers. Those ViewControllers are in the array viewControllersArray = [[NSMutableArray alloc] init]; I add viewControllers on this array like this:

        [viewControllersArray addObject: infoViewController];

After the viewControllers are added on my array:

NSArray *initialViewControllers = [[NSArray alloc] initWithObjects:[viewControllersArray objectAtIndex:0], nil];
[self setViewControllers:initialViewControllers
               direction:UIPageViewControllerNavigationDirectionForward
                animated:YES
              completion:^(BOOL finished){
                  NSLog(@"call back success");}];

This above code is all done in the viewDidLoad from my UIPageViewController.

For loading this array I got those functions form <UIPageViewControllerDataSource> which I use like this:

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
    if ([viewControllersArray containsObject:viewController]) {
        NSInteger index = [viewControllersArray indexOfObject:viewController];
        if (index < [viewControllersArray count] && index > 0) {
            return [viewControllersArray objectAtIndex:(index - 1)];
        }
    }
    return nil;
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
    if ([viewControllersArray containsObject:viewController]) {
        NSInteger index = [viewControllersArray indexOfObject:viewController];
        if (index < [viewControllersArray count] - 1) {
            return [viewControllersArray objectAtIndex:(index + 1)];
        }
    }
    return nil;
}

Now what the problem is, is that when you swipe, the next viewcontrollers gets load, etc. But they don't get unloaded. So I'm searching for a way to unload the viewcontrollers that you already passed to save memory, and when you swipe back they will get reloaded.

Upvotes: 0

Views: 3488

Answers (2)

Johannes Fahrenkrug
Johannes Fahrenkrug

Reputation: 44760

your problem is that you hold on to your view controllers in the viewControllersArray. The array holds a strong reference to each object that you add to it. The easiest way to save memory is to just create the requested view controller on the fly in both the pageViewController:viewControllerBeforeViewController: and the pageViewController:viewControllerAfterViewController: data source methods. That way, only the page view controller will have a strong reference to the view controller and will release (dealloc) it once it is moved off-screen.

If it's too expensive to create them on-the-fly, you might consider just keeping 3 view controllers in the array: the one currently displayed and the one to the immediate left and the immediate right.

Example:

- (UIViewController *)pageViewController:(UIPageViewController *)pvc
      viewControllerBeforeViewController:(MyGreatViewController *)vc
{
    NSUInteger index = vc.position - 1; //custom property on your VC
    if (index > 0) {
      return [[MyGreatViewController alloc] initWithPosition:index];
    }

    return nil;
}

- (UIViewController *)pageViewController:(UIPageViewController *)pvc
       viewControllerBeforeViewController:(MyGreatViewController *)vc
{
    NSUInteger index = vc.position + 1; //custom property on your VC
    if (index <= MAX_POSITION) {
      return [[MyGreatViewController alloc] initWithPosition:index];
    }

    return nil;
}

Enjoy!

Upvotes: 3

FunkyKat
FunkyKat

Reputation: 3223

You should not unload View Controller. If memory is low, controllers unload their views. In code, use -(void)viewDidUnload and -(void)didReceiveMemoryWarning (iOS 6) to free your resources. When UIPageViewController will show some page, controller recreate unloaded view and call -(void)viewDidLoad (if you customize your controllers manually).

Upvotes: 0

Related Questions