0
votes

this is probably a newbie question...

I'm trying to reduce the amount of memory usage in my iPhone app.

I have an UIViewController with a set of buttons. When the user taps any of them, the app takes him to a new screen (new UIViewController).

Should I create them on demand ([[MyUIViewController alloc] initWithNibName:@"MyUIViewController" bundle:nil];), or should I have all these UIViewControllers as @propertys in the "main" controller, and create them only the first time? (check if they are nil).

I noticed (with Instruments) that, following the first approach, the used memory (Live bytes) increases on push but does not decrease when pulling the controller, and so on every time I press a button.

Furthermore, does that also applies to UITableViews, where I push another UIViewController in tableView:didSelectRowAtIndexPath: method?

Thank you in advance.

EDIT: I'm using ARC

5
Generally you should just create controllers on-demand, as you need them, rather than up-front. No need to waste precious memory. - Rob

5 Answers

1
votes

You said:

I noticed (with Instruments) that, following the first approach, the used memory (Live bytes) increases on push but does not decrease when pulling the controller, and so on every time I press a button.

So when you go from VC1 to VC2 are you saying that the memory usage goes up significantly, but isn't dropping as you return to VC1? Have you checked your code for leaks? First, run it through static analyzer (shift+command+B), which can identify some of the most egregious mistakes. You should have zero warnings.

Second, run your code through Instruments via the profiler to identify any leaks. See the "Finding Leaks" section of the Instruments User Guide.

0
votes

Keeping them around and reusing them will keep your apps base memory at a higher level, but will probably increase the performance as these will not need to be recreated on demand.

That being said, the performance of pushing a new view controller is not very bad to begin with (unless you are doing something wrong) so just create them on demand.

If the old VC memory is not being released when popped, you might have a retain cycle somewhere. Look for any delegate code you may have written that is not getting cleared on the dismissal of the view.

0
votes

Generally, a UIViewController should be fairly light on memory. It's the UIView objects that you can save the most memory on, by ensuring you're familiar with the view life-cycle and that you let the views get cleaned up (by not holding references to them anywhere outside the view controller's view property and by setting any other view references to nil in viewDidUnload). There's a good answer here about how to use viewDidUnload.

Having said that, so long as it's not very heavyweight to create your view controllers, it's probably better to re-create them whenever needed. This is not so much for memory reasons, but for simplicity. So unless you need to keep references to them in properties for other reasons keep it simple and use less code - just create them as-needed.

0
votes

This is probably a newbie answer, so please take it with a grain of salt.

In this scenario, I never worry about implementing my view controllers in code. I use the storyboard to create the initial view controller and embed it in a navigation controller. Then, I create subsequent view controllers and link them to the appropriate parts of the initial controller's view through named segues (by control-dragging). I think that by using this technique, a view controller down the chain will only be instantiated once its segue has fired. I'm sure Apple has optimized the heck out of this and so I'm confident that by using the storyboard I'll conserve more memory than by trying to fiddle around with things in code.

0
votes

After chatting with @RobertRyan here (I suppose the link will remain), he gave me the solution: the problem was I was having a retaining cycle in my VC2 (please take a look at the chat so I don't rewrite everything here). Thank you very much @RobertRyan!