【问题标题】:Many view controllers - performance issue许多视图控制器 - 性能问题
【发布时间】:2015-11-05 18:09:30
【问题描述】:

我有一个 IOS 应用程序,可以让用户浏览数周的笔记。每周都有一个 UIViewController - 视图控制器之间的滑动和切换由 UIPageViewController 处理。

在启动时,所有视图控制器都使用它们的数据进行初始化。

当用户滑动时,我会像这样抓住一个视图控制器:

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    if let currentPageViewController = viewController as? SinglePageViewController {
      let currentIndex = currentPageViewController.index
      return self.weeks[currentIndex - 1]
    }
    return nil
  }

该应用程序完美无缺,直到使用了很多周,因此有很多视图控制器。启动时间开始成为一个问题 - 随着时间的推移,这种情况只会变得更糟。

我尝试过在用户滑动时初始化每个视图控制器。像这样:

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        if let currentPageViewController = viewController as? SinglePageViewController {
          let currentIndex = currentPageViewController.index
          let newVC = SinglePageViewController()
          newVC.index = currentIndex - 1
          return newVC
        }
        return nil
      }

这种方法很有效,启动时间也很长 - 但是,现在刷卡变得迟缓并且根本不流畅。

谁能建议如何解决这个问题?

【问题讨论】:

  • 您可以尝试将其设置为,一旦您的应用程序达到某个点(视图控制器的数量),它就会开始回收旧的视图控制器以显示未来几周的注释。跨度>
  • 不要在滑动时初始化视图控制器,而应该在每个方向上初始化一对,而不是只在它们下一个方向初始化。
  • @twist295,你有这方面的例子吗?
  • @pbush25,我也一直在考虑这个问题。但是应该在哪里做呢? - 如果我在“viewControllerBeforeViewController”中创建 3 个新的视图控制器,我怀疑滑动会更加缓慢
  • 我没有示例,我只是头脑风暴,抱歉。另一种选择是将所有视图控制器的初始创建放在操作队列中,并让系统在后台线程上处理所有这些,这可能会让您的应用程序更快地打开。但是,随着时间的推移,这种方法或您的原始方法很容易消耗大量内存。多达 52 个视图控制器是很多的。我提到的另一个选项可能是更好的解决方案。

标签: ios swift uiviewcontroller


【解决方案1】:

第二种方法(按需创建)是正确的方法。如果刷卡变慢,那么是因为您在 init()、viewDidLoad、viewWillAppear 等中花费了大量 CPU 时间......查看初始化并将每个 CPU 密集型任务移动到后台线程。

如果您依赖数据来创建 ViewController,那么您必须提前预加载数据。但是不需要为超过 2 或 3 个预加载数据。如果需要很长时间并且您仍然遇到性能问题,那么您必须接受设备速度不足以满足您的要求,并且您必须向用户展示加载指示器。 (如 UIActivityIndi​​cator)

如果您在优化初始化方面需要帮助,请发布您的代码。

【讨论】:

    【解决方案2】:

    在 UIScrollView 中使用太多 UIScrollView 时,我遇到了类似的问题。我的解决方案是通过使用scrollViewDidScroll 委托方法来监视用户正在查看的位置,连接到我的容器滚动视图,并根据用户滚动的方向填充/删除视图。

    您可以在scrollViewDidScroll 方法中从let direction = scrollView.panGestureRecognizer.translationInView(scrollView.superview!) 获得的方向。

    这种方法对你有用吗?如果你愿意,我可以给你更多我的代码!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多