Will calling the currentViewController method in all view controllers lead to a memory leak in iOS?

I know that there have been many discussions related to this topic. But in all discussions, everything was discussed with two view controllers (A & B). My script is similar but different.

What happens when there are several view controllers, such as A, B, C, D. Thus, the view flow moves as,

Controller A (Home) represents controller controller B (list). Then, View Controller C (Details) is displayed from the View B controller. Then from View Controller C, view controller D (additional details) is displayed. Then from View Controller D, View Controller A is displayed to go directly to Home !!!

What is the best practice for this?

+4
source share
4 answers

Without knowing the structure of the project and the details of how you will display A, B, C, D, E, F, and then from F to A, I would prefer and assume that this could lead to a memory leak, depending on which The design templates you use for your UIViewControllers. As @CaptJak comments on your questions, it's hard to determine how and when it will cause a memory leak, especially if you use a delegation pattern to transfer data around view controllers.

Personally, when I make complex threads, for example, presenting several UIViewControllers and discovering that I need to return to several screens, I will not push the views on the stack until the one I want is on top of the stack (if you use navigation controller), turn off the view controller if it is presented modally, or unwind segments if I use them. There may be a risk that view manager memory may be freed.

I would comment, but I do not have enough reputation. Take my answer with salt as I am still very fresh in iOS development.

EDIT: Thanks for the details provided in the stream of your application. Since you can use presentViewController, I assume you are working in NavigationController? If so, I would use popToViewController or popToRootViewController (if A is your root view controller) for this case instead of re-presenting A from D. If A is again presented from D, I assume that you will have 2 instances of A in your VC stack , which may lead to a memory leak.

PopToViewController Method

 NSArray arrayOfVCs = self.navigationController.viewControllers; for(UIViewController *currentVC in arrayOfVCs) { if([currentVC isKindOfClass:[ViewControllerA class]) { [self.navigation.controller popToViewController:currentVC animated:YES] } } 

PopToRootViewController method (assuming A is your root view in the navigation controller)

 [self.navigationController popToRootViewControllerAnimated:YES] 

EDIT April 12, 2016

I was just thinking about this question, so actually I made a short RnD and just want to share my findings here. I made a crude simple and dirty function to get the stack of all modal view controllers ever presented in my very simple application.

I tested from A → B → C → B → C → B about 20-30 times. Each time I find the time B → C, the memory increases by 0.5 MB (because my screens are simple, but may vary) and eventually increased from 20+ MB to 50+ MB.

In this function, I wrote down the number of view controllers represented on the stack, as well as their names in the array. So far this has worked for me, but you can try and see if it works for you.

 //global variables var vccount = 0 var vcnamelist = [String]() func getPresentingViewStackCount(currentVC : UIViewController!){ if(currentVC.presentingViewController != nil){ vccount = vccount + 1 let vc = currentVC.presentingViewController vcnamelist.append(NSStringFromClass((vc?.classForCoder)!)) getPresentingViewStackCount(vc) } } // to use func someRandomMethod(){ getPresentingViewStackCount(self) } 

Still consider it better to use navigation controllers. This is what they are made for. :)

+3
source

1. If you imagine like this, A-> B-> C-> D-> A, one after another, one above the other, you will get an exception:

Application tried to introduce modally active controller

You cannot present a ViewController that has already been presented, just like you cannot push a ViewController that is already on the UINavigationController stack.

2. If you used Storyboard to create your application, you can use unind-segue to go back to with D.

3.If you used the code to create your application, you can save the weak link A to D and call

 [A dismissViewControllerAnimated:YES completion:nil]; 

in ViewController D as dismissViewControllerAnimated allows dismissViewControllerAnimated to return to A.

- (void) cancelViewControllerAnimated: (BOOL) flag completion: (void (^ __nullable) (void)) completion,
If you consecutively represent multiple view controllers by creating a stack of presented view controllers, calling this method on the view controller below in the stack rejects its immediate child view controller and all view controllers above this child in the stack. When this happens, only the top of the view is rejected in an animated manner; any intermediate view controllers are simply removed from the stack. The top view is rejected using a modal transition style, which may differ from the styles used by other view managers below in the stack.

+1
source

I really believe that you can program + drag and drop from UIButton (or something else that you use to control the flow) to the view controller, which you then want to imagine in order to navigate correctly. Then you let go and choose any presentation method that you want, and when you try it, it should work. I assume that you are using Xcode for this, and I am not sure about other development applications.

This is intended to prevent memory leaks, but note that you will have to create separate files for each individual view controller. Other manual switching forms may result in a memory leak depending on the contents of your situation.

0
source

It's okay if you show the newly created view controller.

-3
source

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


All Articles