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!
Related
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.
i m facing big problem with system libraries allocations.
i didn't get any leaks from my application still so much allocations.i attached various screen shoots. in my application using custom picker which get all images from assert library.which are pick from picker showing images on scroll view.
its screen shot when my app with 35 images on scroll view.if again i pick images from custom picker allocation increased.i am seeing object details its all related to frame Work allocations.not from my application
see the allocation object list response library is DYLD.
its my leaks screen shot
how can we release these allocations? please help me out ?
Just because you have no leaks doesn’t mean you are managing memory correctly. What you have is what I call memory bloat — you are retaining it longer than you need to. (A leak is allocated memory with no references. Bloat is allocated memory that has a reference but should have none.)
http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ will give you some good strategies for using Instruments to find them. (This is a very credible source, so far as I know he still works at Apple.)
make sure your application has no leaked objects and they will also disappear in instruments. For sure its pointing to a system library but it is always a result of your bugs. Select one of them and open the right view. Probably it will show you the right code stack and the allocated line of code.
The other thing you can do: run the static analyzer Product->Analyze it will find all (at least most) your leaks ;)
I'm building an application that reads rss files something like Bing or Pulse, so I've built a class (UIViewController) that shows each individual entry in the feed and a class that contains that list of entries and another class that shows all the feeds at once, and I've not used any xib files so I've implemented a method in each class that gets called after each rotation to reset the frames of the views inside that class. But I'm facing a problem in the memory especially when calling that method when a rotation happens knowing that it just assigns a CGRect to each frame in the view.
So could you please help me to avoid this problem or suggest a different way to avoid it, and am I right about not using xib files or should I use them when ever I can and set the rotation thing inside them (using the auto resizing mask).
And if there is some complex free example like those applications, could any body point me to it.
Any help would be greatly appreciated,
and thanks in advance...
First, there is no reason to avoid nib files when they are useful to you. They are often useful. There is no reason to use nib files when they are not useful to you. If you have complex layout, they are definitely very useful. Whether to use them or not, however, is a personal choice based on the particular application. As a beginner, I would recommend using them and getting comfortable with them, and particularly relying on the Xcode templates to set them up correctly.
Nib files aren't your issue, one way or another here. You're leaking memory, and you need to investigate why. First, run the static analyzer to make sure there are no obvious errors. Then run your app under Instruments (Leaks) and look for large leaks. Then run your app under Instruments (Allocations) and look for what's eating the most memory. That should point you to your error.
The most likely cause, without any insight into your code, is that you are misusing ivars. Make sure that you access your ivars through accessors (except in init, dealloc and in the accessors). Directly accessing your ivars is the #1 cause of memory problems in iOS.
Release the objects properly which has been allocated and defined globally. Do not release the object of your UIViewController when it is active. Most of the leakage problems occur by releasing the object of the UIViewController before it reaches out of scope.
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
My GUI for an iPhone app uses numerous UIViews. The user "flips" through these views when they tap a button to go forward or backward. The views are stored offscreen and are added to an actual view only when the program needs to display it.
During the flip process, the program tells the parent view (a uiscrollview) to remove any existing subview using the removeFromSuperView method, and then adds the new subview, which is the new page that the user should see.
However, after several repeats of this process on the device, the program crashes with gdb exit status 101, which I found is caused by an out of memory error.
I tried diagnosing this problem using the Leaks tool, but to no avail. There is only 1 or 2 small memory leaks and the total mem usage on the device by the program is only 2.5 mb. Is it possible that video memory, not system memory, is running low?
I came across this post regarding backgroundColor and mem usage, but I need further explanation. Should I reduce setting the backgroundColor to prevent the UIView's CALayer from hogging too much memory?
Do you have access to the iphone sample code on apple? Sounds like the PageControl Sample Code program is a good example of what you're looking for. And the sample code programs don't have memory leaks or any such problem :) Link here
When you were using instruments, did you check the ObjectAllocations? I've found that to be more useful than the leaks tool (object allocations is one of the tools leaks includes though). I would think that if video memory were running out it would be a different error, but I could be wrong.
Where are you storing all these views? Specifically, do you have some array (NSArray) that has these views when you flip through them?
The views won't get deallocated unless their reference count goes to zero. Your `[[UIView alloc] init] makes the reference count at 1, adding it as a subview makes it 2, and removing it from a subview makes it 1 again. Seeing as you don't get told of a specific leak, it seems that you're not really leaking as much as storing it somewhere.