问题
I setup UIPageViewController
to forward and backward through some view controllers . I have a problem which is when a view controller adds to UIPageViewController
the memory usage will increase until the compiler gives me Received memory warning
and then app runs too slowly until the app empties the memory and works fine again . How can I navigate through view controllers without increasing memory ? or better to say how can remove current view controller when a new on adds . here is my code :
// Create the page view controller.
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource = self;
//disabling tap and swipe guesture
for (UIGestureRecognizer *recognizer in self.pageViewController.gestureRecognizers) {
recognizer.enabled = NO;
}
// Instantiate the first view controller.
UIViewController *startingViewController = [self viewControllerAtIndex:0];
[self.pageViewController setViewControllers:@[startingViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:^(BOOL finished) {
// Completion code
}];
// Add the page view controller to this root view controller.
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
Forward and Backward actions :
- (void)goToPreviousContentViewController
{
// Get index of current view controller
UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
NSString *vcRestorationID = currentViewController.restorationIdentifier;
NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID];
UIViewController *previousViewController = [self viewControllerAtIndex:index - 1];
[self.pageViewController setViewControllers:@[previousViewController]
direction:UIPageViewControllerNavigationDirectionReverse
animated:NO
completion:^(BOOL finished) {
// Completion code
}];
}
More Codes :
#pragma mark - UIPageViewControllerDataSource
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return self.contentPageRestorationIDs.count;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSString *vcRestorationID = viewController.restorationIdentifier;
NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID];
if (index == 0) {
return nil;
}
return [self viewControllerAtIndex:index - 1];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSString *vcRestorationID = viewController.restorationIdentifier;
NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID];
if (index == self.contentPageRestorationIDs.count - 1) {
return nil;
}
return [self viewControllerAtIndex:index + 1];
}
#pragma mark - Private Methods
- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
// Only process a valid index request.
if (index >= self.contentPageRestorationIDs.count) {
return nil;
}
// Create a new view controller.
BaseContentViewController *contentViewController = (BaseContentViewController *)[self.storyboard instantiateViewControllerWithIdentifier:self.contentPageRestorationIDs[index]];
// Set any data needed by the VC here
contentViewController.rootViewController = self;
return contentViewController;
}
回答1:
To answer your questions
"How can I navigate through view controllers without increasing memory?":
You can't really do that. When you load a new view controller it will load all of it views and the view controller is stored in memory. You can't load and display a view controller that is not in memory.
"How can remove current view controller when a new on adds":
You shouldn't do that. An empty view controller doesn't have a big memory footprint, you can easily have 20+ view controllers in the navigation stack without any memory problem. Although it is possible to implement something like this, it takes a lot of work, and it doesn't solve the root of your problem.
What is the problem then?
You have a memory management problem. It is not caused by the code you have posted, that looks fine. The problem must be in another part of your code.
There are two common cases that could cause memory management issues:
Retain cycles: A retain cycle is essentially when two objects retain each other. This goes against the standard rules of object ownership, leaving both objects with no authority to release the other, causing a memory leak (the numbers are the retain count):
Unnecessary caching: If you are downloading a lot of different images and caching them, that is not the ideal use case for caching. Caching is ideal for storing frequently accessed objects. If you are not frequently accessing these images or receive a didReceiveMemoryWarning message, you should release these objects.
How can you debug memory issues
The first and most simple thing to do is to override the view controller's dealloc method. Overriding the dealloc method on a viewcontroller will help ensure that a viewcontroller is being deallocated when you expect it to be.
-(void)dealloc {
NSLog(@"viewcontroller is being deallocated");
}
If this doesn't help you can try to isolate the problem and debugging it with Xcode Instruments. This article could be a good start for you.
回答2:
To avoid memory and manage view controllers you need to stack all view controllers in a container.
So that every next/previous call will be made on that container and it will provide as your need. Also one more benefit of this container is to avoid reinitialise controller again and again.
Once you add view controller in container you are no need to alloc init or initialise that controller second time.
It's a big code to paste here and also storyboard setup will not be seen. So i share you one demo to visualise and use page controller with container to hold view controllers.
PageDemo
回答3:
I don't see any memory issue in your code. Try using profiler tool called "Leaks" and try to find what object did not released from memory. There is official Apple guide for that
来源:https://stackoverflow.com/questions/32871462/uipageviewcontroller-and-removing-current-view-controller