memory leak in device not in simulator - iphone

I have checked using instruments and not found any memory leaks.
when i check in device it shows memory leaks with responsible caller -[NSKeyedUnarchiver decodeObjectForKey:] and object is UIRoundedRectButton.
I still not using NSKeyedUnarchiver or any type of decoding. Is following code, is responsible for this memory leak ?
- (void)saveToFile:(NSString *)pinStr
{
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *path = [documentsDirectoryPath stringByAppendingPathComponent:#"smsbrain.plist"];
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
[data setObject:#"User" forKey:#"username"];
[data setObject:#"password" forKey:#"password"];
[data setObject:pinStr forKey:#"pin"];
[data writeToFile:path atomically:YES];
[data release];
}
Or i have checked through internet & also some post on stackoverflow but not find any better solution.
I am not setting outlet to nil in viewdidunload & in dealloc methods. is it create any problem?
my application hides background when this leaks occur. and on console i get warning "Memory level is not normal (20 %)"
So, what to do for the problem of invisible of background of tableviewcontroller. it is working fine on simulater. but what is problem in device that it sometime hide background.
please help me...

If you are not doing any NSCoding on yourself, the responsible caller is most likely a UIViewController that is decoding it's nib file. The memory warning you receive fits into this assumption.
When a memory warning is raised the standard implementation of UIViewController will release it's view, if is not visible (doesn't have a superview). As a result all subviews of that view will receive a release message and be dealloced, if no one retains them. But normally the viewController will at least retain some of it's view subviews trough it's IBOutlet properties. This is were viewDidUnload comes into play. It's called right after the view was unloaded (mostly due to a memory warning). This is the place were you really should release all retained subview of your view. That is every IBOutlet and erverything you created in viewDidLoad. There's really no need to hold them. They will all be recreated from the nib when needed.
In your dealloc method you have to release all retained properties and all retained ivars, that do not back a property. Please read the Memory Management Programming Guide
If this doesn't help. We would need your property declarations and the viewDidLoad, viewDidUnload, dealloc methods of the Controller in question.

Related

EXC_BAD_ACCESS When NSSearchPathForDirectoriesInDomains in iOS5

I'm developing an App that will update the UI every time a View "A" appears. I put the related code in the ViewWillAppear and this update will load some images in the document path of the app. Thus, I will load the related path in the section. And it works fine in the beginning, but if I navigate to another page (using navigationController to push page) and back to this page again several times, I will got an EXC_BAD_ACCESS.
Code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); // EXC_BAD_ACCESS here
NSString* docPath = [paths objectAtIndex:0];
.....
And if I temporarily change the code by hardcoding the path like:
NSString* docPath = [NSString stringWithFormat:#"****/****/***/Documents"];
then it will not crash.
I also tried to load the document path at ViewDidLoad and save the value to a variable where the property is (nonatomic, retain).
And in the ViewWillAppear, I load the path like:
NSString* docPath = self.documentPath;
but it will also got an EXC_BAD_ACCESS at this line.
Before this line, I also tried to print the self.documentPath, and it will get the correct path string.
Check out my this answer to see how to debug EXC_BAD_ACCESS error and then put up the error description here. That would help to answer your question.

Object dealloc only crashes in iOS 4.3

I'm trying to figure out why pushing a viewController in my tableView using didSelectRowAtIndexPath would cause a crash in iOS 4.3, but in iOS 5.0+, it works fine.
It crashes right when I call:
self.customViewController = [[[CustomViewController alloc] initWithNibName:#"CustomViewController"bundle:nil] autorelease];
anytime after the first time the customViewController has been pushed.
Here's my relevant code:
#property (nonatomic, retain) CustomViewController *customViewController;
-(void) dealloc // Dealloc of tableView.
{
[customViewController release];
customViewController = nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.customViewController = [[[CustomViewController alloc] initWithNibName:#"CustomViewController"bundle:nil] autorelease]; // Release old, allocate new, set it.
[[self navigationController] pushViewController:customViewController animated:YES];
[customViewController release]; // Balance out pushViewController's retain.
}
Thanks.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.customViewController = [[[CustomViewController alloc] initWithNibName:#"CustomViewController"bundle:nil] autorelease];
[[self navigationController] pushViewController:customViewController animated:YES];
[customViewController release]; // Balance out pushViewController's retain. ---->NO
}
The last release is an extra one that is not needed.
You already have done an autorelease on it to have it's retain count down by one.
We will analyse this line
self.customViewController = [[[CustomViewController alloc] initWithNibName:#"CustomViewController"bundle:nil] autorelease];
you create a CustomViewController retain count == 1.
You say autorelease on it so retain count will be 0 later (probably the end of the run loop), but for now it's still 1 that is why you still have access to it, but treat it as 0.
After that you say self.customViewController, that property is retain, so retain count == 1.
And you are taking care of that 1 in your dealloc.
As of your comment :
// Balance out pushViewController's retain.
You don't Balance those, you balance only the one YOU own. If the system make retain on your objects, it will release them when the system don't need them anymore.
Don't release the customViewController. You've already autoreleased it when you assigned it, so you've already given up ownership from the alloc. You don't have to release or autorelease the object again. The navigation controller takes ownership and will relinquish it by itself at the appropriate time.
Also, it's coincidence that you may see it in one version and not another. This is a memory management problem, so any corruption you might see (crashes, etc.) will be dependent on the state of memory on the device whenever you run the app. You may see a crash all the time, never, or only after running Skype but before opening the Photos app.
A good way to look for these is to enable zombies during your debugging sessions. With zombies enabled, objects are never actually released. Instead they are put into a zombie state and if they're ever sent a message again, they will abort the app and show you where the stray message was sent to help you debug your memory issues.

UIImageView got weird retain count and i need to release it twice to avoid leaks

I got a UIImageView that i set in the nib file. I download an image from internet and sets the image to the UIImageView. When i'm releasing it has retain count 2? If i'm using only 1 release it won't show any memory leak but i can see in "Instrument Allocations" that it never gets released. When i release the UIImageView twice like below then it works good. But i should never release it twice?!?!
in Header:
IBOutlet UIImageView *background;
in the .m loading the image:
/* Load Image code */
id path = [NSString stringWithFormat:#"http://www.image.com/aImage.jpg"];
NSURL *url = [NSURL URLWithString:path];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
[pool release];
in dealloc function:
- (void)dealloc {
NSLog(#"Backgroud count: %i",[background retainCount]); // Prints 2
[background release];
[background release]; // Does not "leak" if i have 2x release
[super dealloc];
}
This is the only code that is useing the UIImageView Background.
EDIT:
something i forgot to mention is that i run this code inside a for loop like this. but this for loop will only execute once! But it shouldn't matter?
for (id theKey in dictionary) {
/* Load Image code above is here */
}
I believe that I've figured out what the trouble is. Apple recommends that you retain the objects you connect to through IBOutlets (your image view, in this case). You said that you haven't done so, but you should be following Apple's recommendation. The reason that you should is outlined in a iphonedevsdk.com forum post about this problem, which links to a Big Nerd Ranch blog post that lays it all out.
On iOS, the nib loading mechanism uses the setter if your outlet has one, but it uses key-value coding if not; specifically, it uses setValue:forKey:, which retains the value (this is documented, but somewhat unexpected). Your image view, being the subview of your view controller's top view, is retained by that view. It's also retained by this key-value setting procedure. So, unbeknownst to you, your objects have two references to the image view. Apple makes the retaining property suggestion so that it becomes knownst to you that the view is being retained.
You still shouldn't be worrying about the retain count as such, but you should do one of two things: make this IBOutlet a retained property and release it in both viewDidUnload and dealloc (just once each, though!), or follow BNR's suggestion and make the property explicitly assigned:
#property (assign, nonatomic) IBOutlet UIImageView *background;
in which case you do not have to release it yourself. In both cases, make sure you #synthesize the property accessors.
Previously:
Don't look at retain count, and if there's no leak being detected, then don't worry about it. The UIKit framework is likely retaining the view for reasons that you aren't privy to.
Additionally, if background isn't a retained property:
#property (retain) IBOutlet UIImageView *background;
and you're creating it in the xib, you shouldn't be releasing it at all, because you don't own it. That is, you aren't responsible for its memory; the actions that give you that responsibility are: calling retain on the object, or creating it using a method whose name begins with alloc, copy, mutableCopy, or new.
I don't know much about nib file, i used to follow like below
background=[[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
//Now the reatin count is 1
[background setImage:[UIImage imageWithData:urlData]];
[someView addSubview:background];
//Now the ratainCount will be 2 since we added the imageview to the superview
[background release];
//i will release immediately so the retain count drops to 1
. . .
//in dealloc or viewDidDisaaper i will remove the imageview from its superview
//then the retainCount will become 0 and the instance will be deallocated.
//it works for we without any memory leakage
[background removeFromSuperview];

how to solve memory leaks in AVAudioPlayer-iphonesdk

how to solve memory leaks in AVAudioPlayer-iphonesdk. here. i will give the my code.. memory leaks are in my code, how to solve it..
.h file
AVAudioPlayer *titlescreenaud;
.m file
titlescreenaud=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"TitleScreen_BgmAudio" ofType:#"mp3"]] error:NULL];//***Memory leaks on here......***
titlescreenaud.numberOfLoops=-1;
[titlescreenaud play];
After finish the sound
-(void)finish
{
[titlescreenaud stop];
[titlescreenaud release];
titlescreenaud=nil;
}
how to release the avaudioplayer please help me.......
titlescreenaud=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"TitleScreen_BgmAudio" ofType:#"mp3"]] error:NULL];//***Memory leaks on here......***
I assume Instruments is indicating that the memory leak is there. What it means is that something allocated on that line has not been released. The actual leak may be elsewhere and will most likely be because of a missing release.
Is your finish method really being called? Do you release titlescreenaud in dealloc?
There isn't enough code here to be able to specifically pinpoint the problem.
If you are allocating AVAudioPlayer object in ViewDidLoad than you will not face the problem. But if you are calling methods repeatatively and in which you have allocated the object than it is always going to allocate the memory for the same object. You can check the retainCount before releasing the memory.

UIWebView memory issues

I am playing youtube videos on a UIWebView which appears as a modalViewController subview (flip transition). Everything works fine, even though the UIWebView is released, I still receive memory warnings after a few repeated selection of this modalViewController.
I have added my UIWebView programmatically inside ViewDidLoad. Inside viewDidDisappear I check for [UIWebView retainCount] and if greater than 1, perform the following steps:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self.webView removeFromSuperview];
self.webView.delegate = nil;
self.webView = nil;
NSLog(#"[self.webView retainCount] %d", [self.webView retainCount]);
I am running my code on xCode 3.2.5, iOS 4.2.
Appreciate all you help.
I think you are approaching the memory management problem in the wrong way. Checking the retainCount is a valid debugging technique if you know what you are doing. It is not, however, a memory management tool. In your particular case, if the UIWebView is being displayed it will always have retain count > 1. The superview will have a retain on it thus making the "if" useless.
If the webView property is well defined (i.e. noatomic, retain) the statement:
self.webView = nil;
should release the webView. A common mistake is to initialize the property with:
self.webView = [[UIWebView alloc] init];
This is likely to introduce a leak if the webView is defined as "retain". The correct way is
self.webView = [[[UIWebView alloc] init] autorelease];
If you can't display your controller several times without running out of memory you have a memory leak. Use Instruments (Leaks in particular) to find hte objects what are note being released properly. This is a good tutorial.
Be careful in keeping your retains and releases balanced and check for leaks.
Your problem will be related to this:
Is it possible to prevent an NSURLRequest from caching data or remove cached data following a request?
Scroll down to my answer for an extension of the accepted answer - i had this problem for days and it's now resolved!