Reducing memory usage by dividing .xib files? - iphone

I'm going back through one of my old apps (my first, actually), and am trying to reduce memory usage in order to stop it from crashing on older devices (I've run it on an old device and profiled with instruments, and it is definitely memory issues that cause it to crash). Unfortunately, when I made the app, I was not very familiar with the common practices of iOS development and structured it very poorly: with one view controller, and one xib file, hiding and showing interface elements as necessary.
Now I am wondering whether it would be worth doing a complete overhaul and starting over, with multiple classes and view controllers, and whether that will reduce the insanely high amount of memory (70+MB) needed to load the app.
Also, would it work if I just emptied out the .xib file and loaded all the interface elements programmatically (and continued using one .xib file)?

It's hard to know how much it will help without knowing what's really going on in your app. Here's some general tips to help you out though:
Split out your view controllers so you have one view controller per view. There are cases where a view controller should actually control multiple views (either for memory efficiency, performance, etc), but use this as a starting point.
Don't put all of your objects in a single XIB. Split it out so you have one XIB per view controller and let iOS load your XIB elements when needed.
Creating interface elements programmatically isn't going to help with memory usage.
Watch what you cache and only keep things in memory if there's a clear performance advantage.
If you decide to rewrite your app, be sure to profile it often using Instruments to measure your progress.

Related

Design by .xib or by .m

Friends,
I have an application, ten pages, but full of buttons(with background images), big size background images, box image for set of controls, etc. I have designed all those in XIB files. It is working fine, but in few minutes, my application shows "Received memory warning level=1". Some developers suggesting me to do designs using .m files, instead of doing it in XIB file. They are telling that it will reduce memory usage of graphics.
Is it true? Will designing by .m file reduce memory usage? Please advice, Thank you.
Did you check if you have memory leaks in your app? XIB files use just constant amount of memory. Also, creating the same interface in the code consumes almost the same amount of memory.
In any case, XIB consumes only a definite amount of memory once you load it.
So, if you receive memory warning not immediately after loading the XIB, but a few second afterwards, the real reason causing the memory warning is definitely elsewhere.
Are you doing retain and release correctly? Run static analyzer from the Xcode, remove all warnings reported, and then use Instruments to see if you have memory leaks.
Designing a UI in Nib-file, or doing the same manually in code makes no difference on memory consumptions. The end result is the same amount of life objects in memory, a Nib-file is only serialized objects, no other magic.
Nib-files and Interface Builder only allows you to design UI faster with drag and drop, instead of trial-and-error in code. All the bonuses that Nib-files comes with has a small price; you must bother yourself to at least read the documentation on how to use them! Otherwise you will get into trouble. You can bet that any person advising against Nib-files flat out, have no idea what they are or how they work, and would not be bothered to learn either.
Go to http://developer.apple.com and search for "nib", you want to at least read "Core Competencies - Nib file", and "Memory Management of Nib Objects". Then decide if Nib-file is good or not for your task at hand.
Yea, it is true that you should do it in code. However, if you are receiving a memory warning, it really does not matter. You will have to remove the contents of on page before creating the contents of the other, otherwise it is the same as just using the .xib file. Infact, I once made an application with lots of windows, and I got the same memory warning message.
It is actually very easy to figure out why (I was surprised when I heard). Basically, every single thing in the .xib file is an object. When you have a lot of objects, you run out of memory. What you need to do is run code similar to te following when you change pages.
- (void) changeToPageOne {
[theSecondElement release];
//Then you make the new interface element
UIImageView *theElement = [[UIImageView alloc] initWithFrame:(CGRect)];
//You will need the coordinates from the .xib file for the CGRect there
[theElement setImage:(UIImage*)];
[theView addSubview:theElement];
}
You do the same thing for the next page. The problem here is that you will need to be able to keep track of the UIImageView, but it is basically just a local variable here. You may want to add it to an array, and just remove the objects in the array when you change pages. I hope this helps!

Pros and cons of using XIBs and doing views programmatically

I want to decide if it is better to use XIBs or to designs my views completely using code.
So far I have read that when you design your views on interface builder they are pre-built, so even if they use more memory the user feels everything is faster.
People say doing everything using code is harder but I find it to be just as easy, so I want to know if anyone has experienced some real speed gains when using nibs.
What have been your experiences, advice, etc?
Thanks!
You should be able to do both -- there are times when building a view programmatically is better/easier, and times when using a .xib is better/easier. Even if you only ever do things one way, you'll run into code that does it the other, and you'll need to be able to deal with that.
If you don't know how to use IB, then building your views in code is certainly easier. That is why you should learn to use IB. Once you understand IB, it's way, way faster to put together most of the view-based UI your app will likely need. IB helps you line things up, center objects, align base lines, connect controls to their targets and actions, etc. I think it's safe to say that everyone who uses IB effectively experiences "real speed gains when using nibs."
You should know how to use both. Performance differences between the two are negligible and should not be the reason that you choose one or the other.
Many people who are new to iOS development have the misconception that nibs (.xib files) are inferior to programmatically creating your UI and that if you use IB you're not a good iOS developer. That view is 100% wrong. IB is created by Apple and in use by Apple's developers to create their own Mac OS X and iOS apps. If IB (as a tool) is good enough to be used by some of the best developers in the world, it's probably good enough for most of us.
In practice I have found that a combination of the two usually fits the bill.
In my own apps I find that .xibs are great for laying out the basics of your views quickly and they allow you to iterate very quickly while giving you a preview of what your view will look like. It's also much easier to use auto layout in a .xib file.
Then when you need to do more advanced things like add fancy animations or move views around that is what IBOutlets are for. Anything that you put into a nib can be referenced through an IBOutlet. This allows you do then programmatically make your view come to life.
Lastly, you should fully understand what a nib (.xib) is doing automagically for you. You should understand what happens when a .xib's objects are unfrozen. There are many resources on the internet to understand .xib files better.
Also, learn how to use .xibs in an encapsulated way. For example, .xibs are crazy useful for things like prototype cells and they allow you to keep your code base modular (much more so than storyboards). Also, you will require less UI code in your view controllers.
Lastly, I always say that people should think of IB/.xibs like jQuery. It's going to save you a lot of time but the best developers still know how to do everything in javascript if they have to.
Good luck and have fun!
TL;DR version
Performance is not a consideration when deciding to use .xibs or not.
Use .xibs because they give you a preview of the view you are creating and they allow you to quickly iterate
In practice most apps will use a combination of both. You will programmatically add animations or move views around but the .xibs will be a starting point
Understand fully what happens when the objects in a .xib are unfrozen
You'll be more productive but be sure you fully understand what is happening behind the scenes.
I would always use XIB files unless there was a reason not to. This allows your views to be maintained easily in the future.
Some reasons for creating the views programmatically might be:
A control needs to be resized,
repositioned or otherwise altered
depending on something else
Controls
need to be added or removed
dynamically
There may be more reasons but there are not too many.
If you programmatically create views when there is no need you make it a lot more difficult for other developers to try to figure out what the view will look like and to change it.
If you build your views programmatically, you have control over the loading of elements. e.g. you could use lazy loading, and load secondary buttons, subviews, etc. a fraction of a second after the more important elements, allowing the key parts of the UI to come up faster. You could even animate some elements into position.
If you use IB, you get guides as to proper element spacings and positioning, but you could always copy the coordinates from IB into code if you aren't changing the design that often.
For simple UI elements, you will end up with more lines of code to maintain if you create them programatically.
IB and NIBs do a lot to optimise loading/unloading of views, but it is largely oriented to minimising memory usage vs. perceived speed for the user. For example, lazy loading if anything might make the app UI slightly slower, but it should make memory usage lower. This in turn could make overall app performance better on a large application, and is very much encouraged, but it's difficult to define "performance" in a narrow way. It's also difficult to say when you should or should not use IB - there will be some times you're much better off doing it in code.
One often overlooked element to the IB or not debate is development speed, especially if you have multiple developers. On a larger team/project you'll probably have some developer(s) who specialise more in the infrastructure, business logic etc. of the app and some developer(s) who specialise more in the UI. In this case, use of IB will make it easier for them to work independently, which should make overall development more efficient.
I view IB as a core part of the development platform for iOS development. It's not the right solution in every situation but not knowing how to use IB will be a real limiting factor.

IPhone memory problems

I am working on an App that is already been made but Memory Management was not considered in the development stages.
So what can I do to keep the App memory usage low as soon as I get a memory warning?
Is there any general tool or some piece of code that I can use to release any unused memory?
Two things.
First, if you're using any sort of view hierarchy (tab bar, UINavigationController, or something you've rolled on your own), the message is going to propagate upward. That means one handler for memory messages in your root-level UIViewController subclass can handle memory events for the whole app, which is very handy.
Second, you want to go after the low-hanging fruit. In the app I'm currently working on I have a couple different arrays of dictionaries that contain my app data, and each of those dicts contains both a thumbnail and a larger image. Obviously those make up the bulk of the bits I'm keeping in memory. So the first thing my root view controller does when it gets a memory warning is go through those data sets and set those images to nil. Because they're retained properties, they get released when the setter is called and the images are freed from memory. Then I have functions in my view controllers to notice the nil-ness of those image fields and reload them from the server.
By the way (okay... two things and a "by-the-way"), memory warnings aren't a problem. Some people seem to feel bad about getting them, want to redesign everything about their app so they never get one. That's really not necessary; even the best-designed app will get warned about memory occasionally, just because of the unpredictability of the background apps on the device. The important thing is to handle them well.
Xcode can be combined with the Instruments tool to show you the places where your application is leaking memory, i.e. where reserved memory is not released properly. CIMGF has a solid tutorial on this: http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/
You should have a look at the method
- (void)didReceiveMemoryWarning
of your UIViewControllers. This method is called when you receive a memory warning. Here you can release objects currently not used. But it's your part to determine what is used and what not.
The "Build and Analyze" feature of XCode is a tool you could use to see if the code contains any obvious memory leaks.
You should have a look at the small section "Memory Management" in the UIViewController class reference:
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html
Also an important document is the "Memory Management Programming Guide":
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

Do I lose performance by using .xib files to provide an iPhone app's GUI?

I was wondering if there is a difference between using .xib files for GUI design and doing this programmatically.
As it is a compiler I would assume that there is no relevant time lost.
Am I wrong?
(Note: Tapping this out on my phone, so I apologize ahead of time for any weird formatting or grammar - if there are issues, I'll fix them when I'm back at my laptop.)
I've done some quick, dirty, and extremely informal tests to check this out for myself, and here's what I found (note that the app I built for the tests was just scratch and not necessarily representative of a "real" app):
Startup time was faster when when the initial screen was a nib
For all subsequent screens, performance increased when coding the UI by hand
It's odd at first, but when you think about it, maybe it isn't really all that strange.
The startup issue confuses me, but I assume it's because Apple, being Apple and being obsessed with startup times (in a good way, of course), just optimized the phone's unarchiver in such a way that loading from an archive (nib) can be faster than coding by hand.
That said, most people write apps that aren't going to be significantly affected by any differences. My (again: quick and dirty) tests showed that, from a cold start (you haven't run the app yet or in a while), the nib-based app consistently loaded its initial screen about twice as fast as the hand-coded version. While that sounds like a big deal, we're talking just a few milliseconds. That difference will be imperceptible to users. For a warm start (you've already opened and closed the app), the differences for startup time were much smaller.
For this reason, I like to use nibs for laying out the foundation of an app: any top-level navigation (tab controllers, nav controllers, etc.), and then code the rest of the UI by hand.
Plus, because the iPhone UI is so specific to, well, the iPhone (surprise!), coding UIs by hand isn't difficult the way it is when writing desktop apps. You use the same UI components over and over - once you've got that down, whipping up a UI in code is easy. You don't have eight-billion widgets to choose from as you would developing a Windows/OS X/whatever application. The iPhone's consistency makes it the easiest platform I've developed against in ages when it comes to hand coding UIs.
I've also found that NSCoding (which is what I use for persisting state across app runs) is much easier to work with when I've hand-coded a UI. I've run into problems where a nib-based screen wouldn't properly archive because of UIImage instances. UIImage (at least the last time I checked) doesn't conform to NSCoding, so the archive process dies (and a rather unpleasant death it is). I used UIImage as an example here, but anything the archiver tries to store that doesn't conform to NSCoding is going to foul up the process, so that's something to think about.
Another time I always code UIs by hand is whenever I'm using a dynamic table. If I'm creating a static table - one whose cells will basically never change - nibs are fine. For any other kind of table, and especially those that have, say, thumbnails and other resource-intensive bits, the control I get when coding by hand makes it possible to get performance you aren't going to get with nib-based table cells. For that, you do have to skip CocoaTouch and work directly with CoreGraphics, but the performance improvements you can make are worth every last line of code you have to write. For examples of table performance from projects I've worked on, see the Barnes and Noble Store (not the ebook reader) and Style.com. We built a framework for those (and other) apps, and the secret to the smooth table scrolling is that we never once used cells loaded from nibs (it's more complex than that, but skipping nibs was the first step to getting the performance you'll see in those apps).
Generally speaking, possibly the most important thing to consider when using nibs is that you need to break your UI up across files. That is, don't stick your app's entire UI into a single nib. When a nib is being loaded, it's the whole thing - there might be a view in the nib your users will rarely, if ever, see, and those get loaded just like everything else, sucking up resources for no reason. If you don't use separate nibs for each of your app's screens, it's easy to run into memory and performance issues.
To further clarify: if you have an app with five view controllers, stick each controller in its own nib. You don't want to load anything until its needed. There are exceptions to this, but that's simply how coding is - given enough time, you'll find a reason to do something "the wrong way," but the a-nib-for-each-screen approach is the way you ought to be doing it unless you have a good reason not to.
I'll leave it there - I hope it helps a little.
Just remember:
My informal mucking around showed that startup was faster with a nib (as long as you keep the nib as simple as possible, keeping only what you need in it).
After startup, performance seemed to improve for hand-coded UIs.
If done correctly, and if you aren't writing a game or something, nibs shouldn't result in perceptible performance issues.
In my experience, tables are different - they're one place I will rarely use nibs.
If you're using NSCoding for persisting app state, nibs can be problematic, and any workarounds probably aren't worth the effort since coding iPhone UIs by hand is relatively easy.
Keep your nibs as simple as possible - I can't say this enough. Wherever possible, create a nib for each screen of your app rather than stuffing your entire app's UI into a single nib.
Ok. Stopping for real this time.
Hope this helps :)
Very little. There are some exceptions. For example, if you use a xib to load the image that goes into a UITableViewCell, then that could be a problem since UITableViews with many cells are sensitive to loading times. However, for all intents and purposes, there should be no noticeable performance hit.
The information in the xib does have to be decoded at runtime and loaded into memory, which is not as fast as just creating UI elements programmatically and directly.
Beware premature optimization, especially when it involves writing a great deal more code than you need to.

Performance penalty for using NIB files?

I am curious to know if anyone has any experience comparing the load time performance of iPhone apps with views laid out in NIBs vs. views laid out entirely programmatically (i.e. instantiating UITextView, adding it to the view, instantiating UIButton, adding it to the view…).
If I want a simple app to load lightning fast, would it be better to forgo using a NIB (well, XIB technically) and instead create view elements programmatically? Is the time spent loading and parsing a NIB sufficient enough to make a noticeable difference?
I've noticed that loading complex interfaces on the iPhone with NIBs is slightly slower. It's only by a fraction of a second, but it's noticeable if the user is expecting to see a sheet or modal view. I think the difference is that NIBs are lazily loaded on the iPhone, so the view is actually created the first time the view is shown - not when the controller and the view hierarchy are first created. That said, it probably only matters on the iPhone :-)
In general, I'd say NIBs are always worth any performance disadvantages that might exist. I wrote iPhone apps back when the SDK first came out and Interface Builder wasn't well tested. Writing code to create view hierarchies was a terrible mess...
In my experience it makes no noticeable difference whatsoever.
And if you think about what's going on with the NIB system, it's a compact binary representation of state of the user-interface objects. By creating the object programmatically, you are only saving the amount of time it takes to load that file and do some very basic parsing. Compare that to the amount of time it takes to initialize and do the first draw of those object (allocating memory for the underlying CALayer objects, drawing them using Quartz2D and then compositing the results together). That time is much greater and it's exactly the same whether you use a NIB or not. If you load a bunch of PNG files to draw your UI, well that will dwarf the time spent on creating the controls.