UIPageViewController并删除当前视图控制器

我设置UIPageViewController来前进和后退一些视图控制器。 我有一个问题,当视图控制器添加到UIPageViewController ,内存使用量将增加,直到编译器给我Received memory warning ,然后应用程序运行太慢,直到应用程序清空内存并再次正常工作。 如何在不增加内存的情况下浏览视图控制器? 或者更好地说当新的on添加时如何删除当前视图控制器。 这是我的代码:

 // Create the page view controller. self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"]; self.pageViewController.dataSource = self; //disabling tap and swipe guesture for (UIGestureRecognizer *recognizer in self.pageViewController.gestureRecognizers) { recognizer.enabled = NO; } // Instantiate the first view controller. UIViewController *startingViewController = [self viewControllerAtIndex:0]; [self.pageViewController setViewControllers:@[startingViewController] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished) { // Completion code }]; // Add the page view controller to this root view controller. [self addChildViewController:self.pageViewController]; [self.view addSubview:self.pageViewController.view]; [self.pageViewController didMoveToParentViewController:self]; 

前进和后退行动:

 - (void)goToPreviousContentViewController { // Get index of current view controller UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0]; NSString *vcRestorationID = currentViewController.restorationIdentifier; NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID]; UIViewController *previousViewController = [self viewControllerAtIndex:index - 1]; [self.pageViewController setViewControllers:@[previousViewController] direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:^(BOOL finished) { // Completion code }]; } 

更多代码:

 #pragma mark - UIPageViewControllerDataSource - (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController { return self.contentPageRestorationIDs.count; } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { NSString *vcRestorationID = viewController.restorationIdentifier; NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID]; if (index == 0) { return nil; } return [self viewControllerAtIndex:index - 1]; } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { NSString *vcRestorationID = viewController.restorationIdentifier; NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID]; if (index == self.contentPageRestorationIDs.count - 1) { return nil; } return [self viewControllerAtIndex:index + 1]; } #pragma mark - Private Methods - (UIViewController *)viewControllerAtIndex:(NSUInteger)index { // Only process a valid index request. if (index >= self.contentPageRestorationIDs.count) { return nil; } // Create a new view controller. BaseContentViewController *contentViewController = (BaseContentViewController *)[self.storyboard instantiateViewControllerWithIdentifier:self.contentPageRestorationIDs[index]]; // Set any data needed by the VC here contentViewController.rootViewController = self; return contentViewController; } 

回答你的问题

  1. “如何在不增加内存的情况下浏览视图控制器?”:

    你真的不能这样做。 加载新的视图控制器时,它将加载所有视图,视图控制器存储在内存中。 您无法加载和显示不在内存中的视图控制器。

  2. “当新的on添加时,如何删除当前视图控制器”:

    你不应该这样做。 空视图控制器没有很大的内存占用,您可以在导航堆栈中轻松拥有20多个视图控制器而不会出现任何内存问题。 虽然可以实现这样的东西,但它需要做很多工作,并且它无法解决问题的根源。

那有什么问题呢?

您有内存管理问题。 它不是由您发布的代码引起的,看起来很好。 问题必须出在代码的另一部分。

有两种常见情况可能导致内存管理问题:

  1. 保留周期:保留周期基本上是两个对象相互保留的时间。 这违反了对象所有权的标准规则,使两个对象无权释放另一个,导致内存泄漏(数字是保留计数):

  2. 不必要的缓存:如果您正在下载大量不同的图像并对其进行缓存,那么这不是缓存的理想用例。 缓存是存储频繁访问的对象的理想选择。 如果您不经常访问这些图像或收到didReceiveMemoryWarning消息,则应释放这些对象。

你如何调试内存问题

第一个也是最简单的事情是覆盖视图控制器的dealloc方法。 覆盖viewcontroller上的dealloc方法将有助于确保在您期望的情况下释放视图控件。

 -(void)dealloc { NSLog(@"viewcontroller is being deallocated"); } 

如果这没有帮助,您可以尝试隔离问题并使用Xcode Instruments进行调试。 这篇文章对你来说是一个好的开始。

要避免内存和管理视图控制器,您需要将所有视图控制器堆叠在容器中。

因此,每个下一个/上一个呼叫都将在该容器上进行,并且它将根据您的需要提供。 此容器的另一个好处是一次又一次地避免重新初始化控制器。

在容器中添加视图控制器后,您无需分配init或第二次初始化该控制器。

粘贴在这里是一个很大的代码,也不会看到故事板设置。 所以我分享了一个演示,可视化和使用带有容器的页面控制器来保存视图控制器。

PageDemo

在此处输入图像描述

我的代码中没有看到任何内存问题。 尝试使用名为“Leaks”的探查器工具,并尝试查找未从内存中释放的对象。 Apple有官方指南