UIPageViewController and removing the current controller

I am setting up a UIPageViewController to move forward and backward through some view controllers. I have a problem where the view controller adds to the UIPageViewController , the memory usage will increase until the compiler gives me a Received memory warning , and then the application will start too slowly until the application empties the memory and stops working again. How can I navigate view controllers without increasing the amount of memory? or better say how to remove the current view controller when a new one is added. 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:

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

Additional 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; } 
+5
source share
3 answers

To answer your questions

  • "How can I navigate view controllers without increasing the amount of memory?":

    You cannot do this. When you load a new view controller, it loads all its views, and the view controller is stored in memory. You cannot load and display a view controller that is not in memory.

  • "How to remove the current view controller when new adds":

    You must not do this. An empty view controller does not have a large amount of memory, you can easily have 20+ view controllers in the navigation stack without any memory problems. Although it is possible to implement something like this, it requires a lot of work, and it does not solve the root of your problem.

What is the problem?

You have a memory management problem. This is not caused by the code you posted, it looks fine. The problem should be in another part of your code.

There are two common cases that can cause memory management problems:

  • Keep Loops: A hold loop is essentially when two objects save each other. This contradicts the standard rules for ownership of objects, leaving both objects without authority to free the other, causing a memory leak (numbers are a saving account):

  • Unnecessary caching. If you upload a lot of different images and cache them, this is not an ideal use case for caching. Caching is ideal for storing frequently accessed objects. If you do not often access these images or receive a didReceiveMemoryWarning message, you should free these objects.

How can you debug memory problems

The first and simplest is to override the controller's dealloc method. Overriding the dealloc method on the viewcontroller will help ensure that the view manager is released when you expect it to be.

 -(void)dealloc { NSLog(@"viewcontroller is being deallocated"); } 

If this does not help, you can try to isolate the problem and debug it using Xcode Instruments. This article may be a good start for you.

+6
source

To avoid memory and managing view controllers, you need to collect all the view controllers in the container.

Thus, each next / previous call will be made on this container, and it will provide you with as much as possible. In addition, another advantage of this container is to avoid reinitializing the controller again and again.

After adding a view controller to the container, you do not need to assign init or initialize this controller a second time.

This is a great code to insert here, and the storyboard setting will not be visible. Therefore, I am sharing with you one demo to visualize and use a page controller with a container for storing view controllers.

PageDemo

enter image description here

+3
source

I do not see a memory problem in your code. Try using the profiler tool called Leaks and try to find which object was not released from memory. There is an official Apple guide for this

+1
source

Source: https://habr.com/ru/post/1232641/


All Articles