Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIPageViewController memory leak

It seems that UIPageViewController is holding the initial content view controller forever. For example:

DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = @[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
self.pageViewController.dataSource = self.modelController;

The startingViewController is never released until the pageViewController itself it released.

To reproduce this bug, just create a new project in XCode using the Page-Based Application template. And add 3 lines of code into DataViewController.m

@property NSInteger debugIndex; // file scope
NSLog(@"DataViewController[%d] created", self.debugIndex); // in viewDidLoad
NSLog(@"DataViewController[%d] dealloc", self.debugIndex); // in dealloc

And when you scroll the demo App in vertical orientation, you'll get logs like this:

DataViewController[0] created  
DataViewController[1] created  
DataViewController[2] created  
DataViewController[1] dealloc  
DataViewController[3] created  
DataViewController[2] dealloc  
DataViewController[4] created  
DataViewController[3] dealloc  
DataViewController[5] created  
DataViewController[4] dealloc  
DataViewController[6] created  
DataViewController[5] dealloc  

DataViewController[0] is never deallocated.

Any ideas about this? Thanks!

like image 367
Jay Zhao Avatar asked Mar 01 '13 11:03

Jay Zhao


1 Answers

Are you using transitionStyle UIPageViewControllerTransitionStyleScroll? I encountered the same or a similar problem which seemed to disappear when using page curl animations instead.

The problem was compounded for me because I was allowing a UISliderBar to set the position in the content. So on change of the UISliderBar, I was calling setViewControllers:direction:animated:completion: which caused more and more view controller references to get "stuck" in my UIPageViewController.

I am also using ARC. I have not found an acceptable way to force the UIPageViewController to let go of the extra view controller references. I will probably either end up using the page curl transition or implementing my own UIPageViewController equivalent using a UIScrollView with paging enabled so I can manage my own view controller cache instead of relying on UIPageViewController's broken view controller management.

like image 132
mwu Avatar answered Sep 27 '22 00:09

mwu