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.
Related
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!
In my app user can take as may picture from camera, so after three time taking the picture it crashed. I can't resize the image (its requirement). So is there any other way to avoid memory leak.
Thanks
There is a know issue with the uiimagepickercontroller with memory leaks.
Apple recommend that you only allocate and instantiate only one instance and store it somewhere for the life of the application (whilst running that is).
Don't create a new one, use it and deallocate it each time you want to
use the control. If you do, your memory usage will keep increasing
until it crashes your app.
Personally I store it as a property in the appDelegate, but there may be a better way of doing it.
Edited: Thanks to CharlieMezak. Yes, such a leak might cause a crash. You'd better do some checking based on CharlieMezak's suggestions.
What may also cause crash is your code trying to access a piece of memory that was deallocated already.
I suggest you first check your code to see if there is any autorelease object that was not taken care of.
Second, turn on NSZombieEnabled, and test your app. If it's indeed trying to access something that was already deallocated (Zombie), the console will show you.
Third, and most importantly, post your crash report and part of the code that might be responsible for such a crash. Your description is somewhat vague, we need to see the report.
It sounds like your app is able to handle the photos correctly (from the user's perspective) two times, but on the third time it crashes. Sounds to me like a memory leak.
If it were a logical error in the code, or an attempt to access a deallocated object, the crash would probably occur the first time you take a photo.
It sounds like you're leaving the images in memory, so by the time you take your third photo, you're out of memory because the first two are still sitting there. Make sure you're releasing what you retain, and if you continue to have trouble, post your code!
I'm having a hard time fixing memory related issues in my iPad application, but, good thing is, that I've learned about "heapshots" because of that. Bad thing is, I'm still unable to figure out what some of the information provided to me means.
So, what are these non-objects which are still alive and takes most of the memory described in Heap Growth? Is it possible to get rid of them? It looks like that most of them are related to various drawing operations, CALayer, context and etc (Category:"Malloc" or "Realloc"). I can provide more details if needed.
It means that memory block was allocated not for an object (e.g. pure c structure).
Usually they are allocated by system framework code, so there are some other objects that leaks. E.g. if you forgot to release UIView, then it's layer will not be freed too.
You can open "Extended detail" panel (see "View" menu) and analyze the call stack. Take in mind that one release you forgot can lead to a lot of memory leaks, so try to fix the easiest leaks and then check whether other leaks disappears.
One more trick. You can disable functional block of your application one by one and see whether leaks disappears. So you will be able to locate module (class, functional block, etc) where it occurs.
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
I'm trying to use XCode's Leaks utility to fix some memory leaks in my code. Is there a better and more understandable way to check for leaks with explanations that pinpoint the exact line and/or offer suggestions?
Another question, I'm using AVAudioRecorder in my code in one of my view controllers. Should I load the recorder in viewDidLoad or in viewWillAppear?
If you're using Snow Leopard, have you tried using the static analyzer?
As mentioned, use Static Analyzer as a first line of defense.
It will not find everything.
But here's the problem with what you are requesting of Leaks. Think about what a leak is - a leak is when you have memory, that should have been released, but it is not.
So that means you are MISSING a line of code, that could have been placed anywhere - doing the actual release at the right time. But how could the tool possibly know when something SHOULD have been released?
So instead, the tool does the next best thing. It tells you where the leaking memory was allocated, then from there it's up to you to figure out where the object travelled and when it should actually have been released.
Static Analyzer will find the cases where you should have released in a few lines of code from when you created the object. Anything else, you just need to use Leaks to get a starting point to track down when you need to release something elsewhere.