UIPageViewController内存泄漏

问题描述:

看来,UIPageViewController永远持有初始内容视图控制器。 例如:UIPageViewController内存泄漏

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; 

startingViewController永远不会释放,直到pageViewController它本身释放。

要重现此错误,只需使用基于页面的应用程序模板在XCode中创建一个新项目。并加入3行代码为DataViewController.m

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

而当你在滚动垂直方向的演示应用程序,你会得到这样的记录:

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]是从未释放。

对此有何想法? 谢谢!

+0

你有没有找到解决这个与ARC解决呢? – 2013-11-06 16:45:53

我有同样的问题,解决了以下内容:

[startingViewController release];其中初始化的终点。

然后第一个ViewController将被释放。

+2

但是我使用ARC ... – 2013-07-05 09:36:11

您是否使用transitionStyle UIPageViewControllerTransitionStyleScroll?我遇到了使用页面卷曲动画时似乎消失的相同或类似问题。

这个问题对我来说很复杂,因为我允许UISliderBar在内容中设置位置。所以在改变UISliderBar时,我打电话给setViewControllers:direction:animated:completion:这导致越来越多的视图控制器引用在我的UIPageViewController中“卡住”。

我也在使用ARC。我还没有找到一种可接受的方式来强制UIPageViewController放弃额外的视图控制器引用。我可能最终会使用页面curl转换或使用启用了分页的UIScrollView实现我自己的UIPageViewController等效,因此我可以管理自己的视图控制器缓存而不是依赖UIPageViewController的破坏视图控制器管理。

+0

是的,我正在使用滚动样式。我实现了自己的PageView,因为没有任何开源实现符合我的要求。 – 2013-12-07 04:08:36

我不确定你是否仍然有问题,但我遇到同样的问题,我找到了解决方案。

我不知道原因,但它的工作原理。

我在addSubview之后设置第一个viewController,而不是在addChlidViewController之前。

-(void)settingPageViewController{ 
if (!self.pageViewController) { 
    self.pageViewController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; 
    self.pageViewController.delegate = self; 
    self.pageViewController.dataSource = self; 
    [self addChildViewController:self.pageViewController]; 
    [self.pageViewController didMoveToParentViewController:self]; 
    [self.containerView addSubview:self.pageViewController.view]; 
    [self.pageViewController setViewControllers:@[[self viewcontrollerAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; 
}  
} 

第一个viewController会在正确的时间释放。

另外,我发现如果在呼叫

 [self.pageViewController setViewControllers:@[[self viewcontrollerAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished){ 
     NSLog(@"finished : %d",finished); 
    }]; 

addSubView前完成块不会叫。

我想这块是第一个viewController没有释放的原因。

我会去找出它为什么没有回调,完善答案〜

欢呼

+0

这个应该被接受。 – 2015-09-02 16:47:22

+0

是的,这是我工作的唯一解决方案!文档没有声明这是一个需求,但这是我获得dealloc被调用的唯一途径。 – 2017-03-27 06:01:33

尝试几次后,搞清楚发生了什么事就类似的问题,我注意到,在我的项目有2个导致保留问题的原因,导致UIPageViewController被永久保留。

1)有在UIPageViewController和呈献给所述的UIViewController之间循环引用(这是固定在这两个类从强改变的属性,以弱)

2)和主固定在改变

[self setViewControllers:@[initialDetailsViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; 

__weak __typeof__(self) weakSelf = self; 
    [weakSelf setViewControllers:@[initialDetailsViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; 

我希望这可以帮助别人

同样的问题,在这里我 通过保持变量 我最初的viewController和,而不是建立在特定的PageIndex相同的VC,我只是重复使用它

+0

你能帮助我的代码片段?提前致谢。 – Ashik 2017-01-30 11:33:07