Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
254 views
in Technique[技术] by (71.8m points)

ios - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...