整个视图控制器中的多个presentViewController方法调用会导致iOS中的内存泄漏吗?

时间:2016-03-31 09:56:58

标签: ios memory-leaks uiviewcontroller automatic-ref-counting presentviewcontroller

我知道有很多关于这个话题的讨论。但在所有讨论中,所有讨论都与2个视图控制器(A& B)进行了讨论。我的情况类似但不同。

当有多个视图控制器(如A,B,C,D)时会发生什么。所以呈现流程移动为,

视图控制器A(主页)显示视图控制器B(列表)。然后从View控制器B呈现View Controller C(Details)。然后从View Controller C呈现View Controller D(Advanced Details)。然后从视图控制器D呈现视图控制器A,以便直接导航到主页!!!

最佳做法是什么?

2 个答案:

答案 0 :(得分:3)

Not knowing your project structure and details of how you will display A,B,C,D,E,F and then from F back to A, I would take a wild guess and say that it may lead to a memory leak depending on what design patterns you employ to your UIViewControllers. As commented by @CaptJak in your questions, it has hard to tell if, how and when it will cause a memory leak, especially if you use delegation pattern to pass data around view controllers.

Personally, when I do complicated flows such as presenting multiple UIViewControllers and find myself needing to go back a few screens, I will neither pop the views on the stack up until the one I want is on top of the stack (if you are using navigation controller), dismiss view controller if it is presented modally, or unwind segues if I use them. The risk here might be the view controller's memory may have deallocated.

I would have commented but I don't have enough reputation. Take my answer with a grain of salt as I am a still quite fresh in iOS development.

EDIT: Thank you for the details provided in your app flow. Since you could use presentViewController, I am assuming you are running on a NavigationController? If that is the case, I would use popToViewController or popToRootViewController (if A is your root view controller) for this case instead of presenting A from D again. If A is presented from D again, I am guessing that you will have 2 instances of A in your VC stack which may lead to 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 navigation controller)

[self.navigationController popToRootViewControllerAnimated:YES]

EDIT 12 April 2016

I have just been thinking about this question so much that I actually did a short RnD on it and just want to share my findings here. I made a crude simple and dirty function to get a stack of all modal view controllers ever presented in my very simple app.

I tested by from A -> B -> C-> B -> C -> B about 20 - 30 times. Everytime I go time B -> C, the memory increased by 0.5MB (because my screens are simple but yours may differ) and ended up increasing from 20+ MB to 50+ MB.

In this function I recorded the number of presented view controllers in the stack and also their names in an array. So far it worked for me but you can give it a 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 think its best to use navigation controllers though. It's what they are built for. :)

答案 1 :(得分:-3)

如果您将显示新创建的视图控制器,那么没什么不好。