Reputation: 916
I'm just starting iOS programming and am playing around with trying to switch view controllers programatically (i.e. go from one view to another). I know that the view controller that presents the next view controller needs to be released after the other one is presented but I can't seem to get anything that works. I have tried dismissing the controller after presenting the next controller but I still get a memory leak.
So I have this code in ViewControllerA
:
- (void) switchViews {
[self presentViewController:[[ViewControllerB alloc] init] animated:NO completion:nil];
}
and this in ViewControllerB
:
- (void) switchViews {
[self presentViewController:[[ViewControllerA alloc] init] animated:NO completion:nil];
}
Buttons in the views fire these events and basically they just switch from one view to the other.
So how do I switch views back and forth so that a memory leak isn't created? And as a side note I am using ARC.
Upvotes: 4
Views: 4529
Reputation:
Basically what you are doing in your code above is creating ViewController A, then ViewControllerB, then another ViewController A, and then another ViewController B and then another ViewController A, and then another ViewController B.
What you should be doing is start with ViewController A, create ViewController B, and then to go back to ViewController A, just dismiss Viewcontroller B.
Read this blog for advice on how to do it the simple way that I've explained.
Now, there is a chance that using this method can cause some problems, and they will most likely only happen when you want to do a little more than just dismiss the current ViewController. Apple does, in fact state in their docs:
"When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it. Although there are several techniques for notifying the presenting view controller that its presented view controller should be dismissed, the preferred technique is delegation."
Now, as the answer from @LeoNatan has said, it can be bad practice to do this by using [self dismissViewControllerAnimated:completion:
. And the above paragraph is why, I believe, he said that it was a bad idea.
It is, indeed good practice to learn how to do it both ways. And although my answer is the quick way, it is also a little dirtier.
Upvotes: 3
Reputation: 57040
This should be a good exercise for you, studying Objective C and design patterns.
Create a ViewControllerBDelegate protocol with a "viewControllerBDidClose:" method. Create a property in ViewControllerB called "delegate". Now, after creating vcB in vcA, set the delegate object to be vcA. Now, when you want to go back to vcA from vcB, you should notify the delegate that you wish to close vcB. vcA would then "dismissViewController:animated:" vcB.
This design pattern is called delegation and presents a two-way "conversation" between an object and its delegate. The delegate "converses" with the object by using the public API, while the object "converses" with its delegate using the delegation protocol.
In the comments, someone recommended that you dismiss vcB from itself. This is a bad practice, and is never recommended. Whoever presented a view controller should be the one to dismiss it. By way of delegation, you notify the presenter that the presented is finished and that the presenter should dismiss the presented.
Upvotes: 1