问题
I know there has been a lot of discussions occurred related to this topic. But in all discussions all have discussed with 2 view controllers (A&B). My scenario is similar but different.
What will happen when there are multiple view controllers like A,B,C,D. So the presenting flow moves as ,
View controller A (Home) presents View controller B(List). Then from View controller B presents View Controller C (Details).Then from View Controller C presents View Controller D(Advanced Details). Then from View Controller D presents View Controller A , in order to navigate straight to Home !!!
What is the best practice for that ???
回答1:
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. :)
回答2:
1.If you present like this , A->B->C->D->A,one by one ,on top of each other,you will get an exception:
Application tried to present modally an active controller
You cannot present a ViewController that is already been presented,just like you cannot push a ViewController that is already in the UINavigationController's stack.
2.If you used Storyboard to build your app, you can use unwind-segue to jump back to A from D.
3.If you used code to build your app , you can keep a weak reference of A in D,and call
[A dismissViewControllerAnimated:YES completion:nil];
in ViewController D as dismissViewControllerAnimated
let you go back to A.
-(void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion;
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
回答3:
I do believe it is possible to command + drag from a UIButton (or whatever else you are using to control your flow) to the view controller that you next want to present, so as to navigate properly. Then, you let go and select whatever method of presentation you want, and when you try it, it should work. I am assuming you use XCode for this, and I am not sure for other development applications.
This is designed to prevent a memory leak from occurring, but do note that you will have to create separate files for each separate view controller. Other manual forms of switching may result in memory leaks, depending on the contents of your situation.
回答4:
Nothing bad if you will display newly created A view controller.
来源:https://stackoverflow.com/questions/36330047/will-multiple-presentviewcontroller-method-calls-throughout-the-view-controllers