在UIPageViewController中释放未使用的页面 [英] Releasing unused pages in 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屋!