UIPageViewController在内存不足时翻转过快时崩溃 [英] UIPageViewController crashes when flipped too fast during low memory

查看:289
本文介绍了UIPageViewController在内存不足时翻转过快时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I had some memory problems due to Xcode's template for a UIPageViewController caching all the page data, so I changed it to load the pages dynamically, so now when my app receives a low memory warning, it releases the memory for page's not showing, but if the user is flipping through the pages real fast by tapping the edge of the screen, it still crashes. I'm guessing this is because it can't free the memory fast enough when didReceiveMemoryWarning gets called. If the user is flipping slowly, it works fine. I limited the speed at which the user can flip pages, but it still happens. I want to be able to free up the memory every time the page is turned, and not have to wait for a low memory warning. I'm using ARC. Is there a way to do this? Or what else can I do to prevent this? Thanks.

编辑:

(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];
}


推荐答案

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

I think you hypothesis is correct, since I also experienced a similar behavior: when you flip to the next page, also for the sake of animating things nicely, the new page is allocated before the old one is deallocated and it takes some times for the old one to be deallocated. So, when you flip fast enough, objects are allocated faster than they are deallocated and eventually (actually, pretty soon), your app is killed due to memory usage. The deallocation delay when flipping pages becomes pretty obvious if you follow the allocation/deallocation of memory in Instruments.

你有三种方法,IMO:

You have three approaches to this, IMO:


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

  1. implement a "light" viewDidLoad method (actually, the whole initialization/initial display sequence): in some app, it makes sense, e.g., to load a low resolution image instead of the high resolution image that will be displayed; or, slightly delaying the allocation of additional resources your page need (db access, sound, etc.);

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

use a pool of pages, say an array of three pages (or 5, it depends on your app), that you keep "reusing" so that the memory profile of your app remains stable and avoid spikes;

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

careful review the way you allocate and release memory; in this sense, you often read that autorelease add some "inertia" to the release/deallocation mechanism, and this is pretty easy to understand: if you have an autoreleased object, it will be released by its release pool only when you cycle through the main loop (this is true for the main release pool); so, if you have a long sequence of methods that are called when flipping page, this will make the release/dealloc happen later.

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

There is no magical bullet when it comes to memory usage optimization, it's a pretty detailed and hard work, but IME you will be able to reduce the memory profile of your app if you review your code and apply those 3 guidelines. Especially, inspecting the spikes of memory allocation in Instruments and trying to understand to what they relate is extremely powerful.

这篇关于UIPageViewController在内存不足时翻转过快时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆