UIPageViewController在内存不足时翻转过快时崩溃

Mar*_*rty 19 ios automatic-ref-counting uipageviewcontroller

由于Xcode的UIPageViewController模板缓存了所有页面数据,我遇到了一些内存问题,因此我将其更改为动态加载页面,所以现在当我的应用程序收到内存不足警告时,它会释放内存以便页面不显示,但如果用户通过点击屏幕边缘快速翻阅页面,它仍然会崩溃.我猜这是因为当调用didReceiveMemoryWarning时,它无法足够快地释放内存.如果用户缓慢翻转,它可以正常工作.我限制了用户翻页的速度,但它仍然会发生.我希望每次翻页时都能释放内存,而不必等待低内存警告.我正在使用ARC.有没有办法做到这一点?或者我还能做些什么来防止这种情况发生?谢谢.

编辑:

(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(SinglePageViewControllerSuperclass *)viewController];
    if ((index == 0) || (index == NSNotFound)) {
        return nil;
    }

    index--;
    return [self viewControllerAtIndex:index];
} 

(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(SinglePageViewControllerSuperclass *)viewController];
    if (index == NSNotFound || index == MAX_PAGE_INDEX) {
        return nil;
    }

    return [self viewControllerAtIndex:++index];
}
Run Code Online (Sandbox Code Playgroud)

ser*_*gio 5

我认为你的假设是正确的,因为我也经历了类似的行为:当你翻到下一页时,为了使事情很好地动画,新页面在旧的页面被释放之前被分配,并且需要一些时间旧的一个被解除分配.因此,当你足够快地翻转时,对象的分配速度比它们被解除分配的速度快,并且最终(实际上很快),你的应用程序因内存使用而被杀死.如果您按照内存的分配/释放,翻页时的释放延迟变得非常明显Instruments.

你有三种方法,IMO:

  1. 实现"光" viewDidLoad方法(实际上,整个初始化/初始显示序列):在某些应用中,例如,加载低分辨率图像而不是将要显示的高分辨率图像是有意义的; 或者,稍微延迟页面所需的额外资源分配(数据库访问,声音等);

  2. 使用一个页面池,比如一个三页(或5个,取决于你的应用程序)的数组,你继续"重用",以便你的应用程序的内存配置文件保持稳定并避免尖峰;

  3. 仔细检查分配和释放内存的方式; 从这个意义上说,你经常读到自动释放为释放/释放机制添加了一些"惯性",这很容易理解:如果你有一个自动释放的对象,只有当你循环通过它时,它才会被它的释放池释放.主循环(对于主发布池,这是正确的); 因此,如果您在翻页时调用了很长的方法序列,这将使发布/ dealloc稍后发生.

在内存使用优化方面没有神奇的内容,这是非常详细和艰苦的工作,但是如果您查看代码并应用这3条准则,IME将能够减少应用程序的内存配置文件.特别是,检查仪器中的内存分配峰值并尝试理解它们之间的关系是非常强大的.

  • 一些额外的有用信息:一位 Apple 工程师告诉我,从 iOS6 开始,“viewWillAppear”在页面第一次变得可见时(开始翻页时)被调用,而“viewDidAppear”在页面完成翻页时被调用。我还没试过,只是想我会提到。使用它,您可以锁定翻页功能,直到前一页完成(通过忽略手势/触摸)。 (2认同)