在UIPageViewController中释放未使用的页面 [英] Releasing unused pages in UIPageViewController

查看:82
本文介绍了在UIPageViewController中释放未使用的页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用单独的 .h .m .xib 基于 UIPageViewController 的图书的每个 UIViewController 页面的文件。每个页面都加载了动画,音乐等,并占用大约4MB的内存。在Instruments中,每个页面加载时,可用内存下降约4MB。翻页时,永远不会释放此内存。它最终会给出内存警告。 UIPageViewController 似乎保持每个页面在内存中实例化,并且不会卸载它。因此,当页面快速转动时,应用程序崩溃。

I am using a separate .h, .m, and .xib files for each UIViewController based page of a UIPageViewController based picture book. Each page is loaded with animations, music, etc. and takes about 4MB of memory. In Instruments, the free memory drops down about 4MB as each page is loaded. This memory is never released as the pages are turned. It eventually gives memory warnings. UIPageViewController seems to keep each page it instantiates in memory and won't unload it. So when pages are turned fast, the app crashes.

我希望能够卸载除<3 c $ c> UIPageViewController所需的3之外的所有页面 - 前一页,当前页和下一页。如何卸载不需要的页面,因为它们是由 UIPageViewController 实例化的。

I would like to be able to unload all pages except the 3 needed by UIPageViewController - the previous, current, and next pages. How can I unload undesired pages since they were instantiated by UIPageViewController.

下面是 UIPageViewController 拉出的页面数组。所有页面(Page1,Page2等)基本上只是加载图像文件,提供基本动画,并有音乐。

Below is the Array of the pages that UIPageViewController pulls from. All of the pages (Page1, Page2, etc.) basically just load image files, provide basic animation, and have music.

    //ARRAY OF PAGES    
pageArray = [[NSArray alloc] initWithObjects:
        (id)[[Page1 alloc] initWithNibName:nil bundle:nil],
            [[Page2 alloc] initWithNibName:nil bundle:nil],    
            [[Page3 alloc] initWithNibName:nil bundle:nil],    
            [[Page4 alloc] initWithNibName:nil bundle:nil],    
            [[Page5 alloc] initWithNibName:nil bundle:nil],    
            [[Page6 alloc] initWithNibName:nil bundle:nil], 
            [[Page7 alloc] initWithNibName:nil bundle:nil],
            [[Page8 alloc] initWithNibName:nil bundle:nil],
             // continues all the way up to page 47
             [[Page47 alloc] initWithNibName:nil bundle:nil],
             nil];

我遗漏了 UIPageViewController的标准初始化。它使用 nextPageNumber 从上面的 pageArray 中提取右页以创建新的页面对象。

I've left out the standard initialization for UIPageViewController. It uses "nextPageNumber" to pull the right page from the pageArray above to create a new page object.

-(void)turnPageForward{

[pageController setViewControllers:[NSArray arrayWithObject:[pageArray objectAtIndex:nextPageNumber]]
                         direction:UIPageViewControllerNavigationDirectionForward
                          animated:YES completion:^(BOOL finished){
                          }];

}

我试过创建一个对象 pageIndex (见下文)在将其提供给 pageController 后设置为nil。它没用。页面提升后页面仍然占用内存。

I have tried creating an object "pageIndex" (see below) that is set to nil after providing it to the pageController. It didn't work. The page still took up memory well after the pages had advanced.

//PROGRAM PAGE FORWARD

- (无效)turnPageForward {

-(void)turnPageForward{

UIViewController * pageIndex =[pageArray objectAtIndex:nextPageNumber];  //nextPageNumber is the next page to load

[pageController setViewControllers:[NSArray arrayWithObject:pageIndex]
                         direction:UIPageViewControllerNavigationDirectionForward 
                          animated:YES completion:^(BOOL finished){
                          }];                                  
pageIndex = nil;                            

}

我看过了stackoverflow用于使用相同的方式向 UIPageViewController 提供页面的帖子,但是没有找到任何关闭的内容。最接近的是 ARC在导航控制器中返回时不释放内存,但不会以相同的方式设置视图控制器。

I've looked through stackoverflow for posts using the same way of supplying pages to UIPageViewController, but haven't found anything close. The closest was "ARC not releasing memory when going "back" in navigation controller" but doesn't set the view controllers the same way.

我试图将不需要的页面设置为nil,因此ARC可以删除它们而没有运气。我应该尝试任何建议或替代路径?我喜欢页面卷曲效果,并且无法在其他地方找到一个好的水平卷页。

I've tried to set the undesired pages to nil so ARC can remove them with no luck. Any suggestions or alternate paths I should try? I like the page curl effect and have not been able to find a good one elsewhere that does horizontal page curls.

谢谢! Eric

推荐答案

UIPageViewController似乎保持每个页面在内存中实例化

"UIPageViewController seems to keep each page it instantiates in memory"

不,你是通过实例化所有这些页面(控制器)并将它们放入一个数组中来实现的(当你转动页面时内存会跳转,因为控制器的视图在显示之前实际上并未加载,甚至尽管控制器已经实例化了。但是一旦你完成了,你的控制器就会保留它的视图并且数组会保留控制器。你只需要保留一些关于你所在页面的数量,并在viewControllerBeforeViewController:和viewControllerAfterViewController:的实现中,在那里实例化一个页面。当您离开该页面时,其控制器将被取消分配。如果加载速度很慢,您可能需要保留一个包含当前页面的数组以及之前和之后的数组 - 如果您将其设置为滚动而不是页面卷曲以进行转换,则UIPageViewController会执行此操作。

No, you're doing that by instantiating all those "pages" (controllers), and putting them into an array (the memory jumps as you turn the page because the controller's view is not actually loaded until you display it, even though the controller has been instantiated. But once you've done that, your controller retains its view and the array retains the controller). You just need to keep some kind of count of which page you're on, and in the implementation of viewControllerBeforeViewController: and viewControllerAfterViewController:, instantiate a page there. When you go away from that page, its controller will be dealloc'd. If the loading is slow, you might need to keep an array that has the current page and the ones before and after -- UIPageViewController does do that if you have it set to scroll instead of page curl for the transition.

我制作了一个这样的简单测试应用程序:

I made a simple test app like this:

@implementation ViewController {
    int count;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    count = 1;
    self.pager = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationDirectionForward options:nil];
    self.pager.dataSource = self;
    self.pager.delegate = self;
    Page1 *first = [[Page1 alloc] initWithNibName:@"Page1" bundle:nil];
    [self.pager setViewControllers:@[first] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    [self addChildViewController:self.pager];
    [self.view addSubview:self.pager.view];
    [self.pager didMoveToParentViewController:self];
}


-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
    if (count > 1) {
        NSString *nibName = [@"Page" stringByAppendingFormat:@"%d",count-1];
        UIViewController *prev = [[NSClassFromString(nibName) alloc] initWithNibName:nibName bundle:nil];
        count -= 1;
        return prev;
    }
    return nil;
}

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
    if (count < 3) {
        NSString *nibName = [@"Page" stringByAppendingFormat:@"%d",count+1];
        UIViewController *next = [[NSClassFromString(nibName) alloc] initWithNibName:nibName bundle:nil];
        count += 1;
        return next;
    }
    return nil;
}

我的例子只有3页,但它说明了一种方法。我将日志放入3个控制器的dealloc方法中,当我离开它们时调用它们。

My example only has 3 pages, but it illustrates one way to do this. I put logs in the dealloc methods of the 3 controllers, and they were called when I navigated away from them.

这篇关于在UIPageViewController中释放未使用的页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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