Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segues and clearing historical ViewControllers from memory

I have an iPad app which has a lot of screens and a lot of segue options. At the moment, I am simply using performSegueWithIdentifier to initiate these segues, and my fear is that I'm taking up a lot of memory as the user performs more and more segues. I've seen that people recommend using the function popToRootViewControllerAnimated: if using a UINavigationController, but the problem is that I'm not using one. How can I stop the number of VC's proliferating? The way the app works, the user does constantly return to the root VC - effectively a search screen. So if I could clear the stack of VC's when such a segue is needed, that would solve my issue I think, but I have no idea how to go about this. Thanks for any suggestions.

like image 819
Scoop Avatar asked Jan 01 '13 09:01

Scoop


2 Answers

When you are using segues the flow moves backwards and forwards. When the user moves backwards (ie presses "back") then it will not push to a new VC but it will pop to a VC that already existed. When you pop, the current VC is removed from the stack and memory.

If you have segues to move backwards in the flow then this is wrong. You only need segues to move forward.

A PROPER PREPARE FOR SEGUE

In prepare for segue you should never create your own view controllers and push to them. The storyboard is there to do all of this for you.

A proper prepareForSegue method should look something like this...

- (void)prepareForSegue:(UIStoryBoardSegue*)segue
{
    if([segue.identifier isEqualToString:"SomeSegue"])
    {
        MyNewViewController *controller = segue.destinationViewController;

        controller.someProperty = "some value to pass in";
    }
}

That is all you need. Note that you only need this if you intend to pass some information to the new view controller. If you are not passing anything forward then you don't need this method at all.

When the method ends the new VC will get pushed onto the screen by the storyboard file.

UNWIND SEGUES

If you have a random flow (like in your comment) then you can use unwind segues to achieve this.

In you 'A' view controller have a function like...

- (IBAction)someUnwindAction:(UIStoryboardSegue*)sender
{
    //some action to run when unwinding.
}

It needs to receive a UIStoryboardSegue object. If set up as an IBAction you can also access it from Interface Builder.

Now when you want to go A > B > C > B > A then just used the standard push and pop (from the segue and back button).

When you want to go A > B > C > A then you can use the unwind segue from controller C.

If you have a cancel button or something in controller C and this is in the Interface Builder and this should take you back to controller A. Then in the Interface Builder underneath controller C you will have a little green square with a door and an arrow pointing out of it. Just point the action of the cancel button to this symbol and choose "someUnwindAction". (Note, unwindAction is in A, button is in C.) XCode then uses this to pop you all the way back to A and deals with removing any memory and stuff. If you want you can send additional information back to A too.

If you want to access this unwind segue from C programmatically then you can run...

[self performSegueWithIdentifier:"someUnwindAction" sender:nil];

This will also pop back to A.

like image 117
Fogmeister Avatar answered Oct 06 '22 13:10

Fogmeister


imho I don't see any issues with using segues, it is much more simple than anything else. If you worry about memory consumed then just profile your app and see how much it eats and how often your "memory pressure handler" is called.

like image 1
Cynichniy Bandera Avatar answered Oct 06 '22 13:10

Cynichniy Bandera