Is this a possible memory leak? - iphone

-(IBAction) btnLoginPressed{
Login *loginOverView = [[Login alloc] initWithNibName:#"Login" bundle:nil];
[self.navigationController pushViewController:loginOverView animated:YES];
[loginOverView release];
}
loginOverView will never get released?

Why do you think it will never get released?
You have done the right thing by balancing the init with a release.
(in the second line the navigationController does retain login but it will release it itself when it is necessary)

You have released the object which you have taken ownership of through alloc or new. So according to the Memory Management guidelines you must release it. So you have done the right thing.

Related

pushing viewcontroller using ARC?

I have two scenario for the project with ARC and project without ARC.
1) The project without ARC.we can use the following.
MyViewController* viewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
2)How can I achieve the above in the project which is with ARC.
a)where can I allocate memory?
b)where can I release viewcontroller after pushing?
c)is there any standard for it?
When using ARC you do not need to release the viewController, the compiler will add the release and retain for you..
So in ARC this will do:
MyViewController* viewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
Using retain, release and autorelease will result in a compiler error.
Be aware that you will need to use the #property correctly when using ARC. Use strong for properties that you want to retain and weak for properties that you just want to assign. If you want iOS 4.3 support you can't use weak but should use unsafe_unretained.
In ARC you don't user release, autorelease or retain. ARC does that for you. You simply allocate it as usual with [[Class alloc] init]; but you don't need to send the above messages to your object.
The pushing of the view controller with the ARC enabled is very simple:
MyViewController* viewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
This is because ARC automatically counts the active pointers to the allocated objects, and when the there are no active pointer to the object, the object is automatically released for you. So you don't have to call those methods yourself.
MyViewController* viewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
Thats it only if you are using ARC, no need to release the viewcontroller after pushing, as ARC takes care of all releases and it inserts itself all the releases at compile time only, so it will work fine.

dismissModalViewControllerAnimated works but not releasing memory (ARC enabled )

Please see below sample . Every thing works but memory is not released. Here MYTest is not getting released and memory seems to be increasing when watched in instruments tool
- (IBAction)methodXYZ:(id)sender
{
MYTest * myTest = [[MYTest alloc]initWithNibName:#"myNib" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: myTest];
[self presentModalViewController:navigationController animated:YES];
}
}
and in myTest when finished i call
[self dismissModalViewControllerAnimated:YES];
i also tried setting delegate and dismissing from parent , but that also doesnt solve the issue ..
Any help will be greatly appreciated.
Thanks
mia
If ARC is enabled (be sure it is) you dont need to worry about it, the system will dealloc the memory when it's necessary.
In the other hand, I invite you to take a look at the classic way (non ARC), its useful sometimes if you want to have a control of the memory like it seems you want.

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.

IPhone SDK - Leaking Memory with performSelectorInBackground

Maybe someone can help me with this strange thing:
If a user clicks on a button, a new UITableView is pushed to the navigation controller. This new view is doing some database querying which takes some time. Therefore I wanted to do the loading in background.
What works WITHOUT leaking memory (but freezes the screen until everything is done):
WorkController *tmp=[[WorkController alloc] initWithStyle:UITableViewStyleGrouped];
self.workController=tmp;
[tmp release];
[self.workController loadList]; // Does the DB Query
[self.workController pushViewController:self.workController animated:YES];
Now I tried to do this:
// Show Wait indicator
....
WorkController *tmp=[[WorkController alloc] initWithStyle:UITableViewStyleGrouped];
self.workController=tmp;
[tmp release];
[self performSelectorInBackground:#selector(getController) withObject:nil];
}
-(void) getController {
[self.workController loadList]; // Does the DB Query
[self.navigationController pushViewController:self.workController animated:YES];
}
This also works but is leaking memory and I don't know why !
Can you help ?
By the way - is it possible for an App to get into AppStore with a small memory leak ? Or will this be checked first of all ?
Thanks in advance !
No, small memory leaks will not (most likely) you application to be rejected from appstore.
In your example as you run your method in separate thread you should create and dispose NSAutoreleasePool object for that thread to handle autoreleased objects. Following changes to getController method should do the trick:
-(void) getController {
NSAutoreleasedPool *pool = [[NSAutoreleasedPool alloc] init];
[self.workController loadList]; // Does the DB Query
[self.navigationController pushViewController:self.workController animated:YES];
[pool release];
}
For more details see Autorelease Pools section in memory management guide. Relevant quote from there:
If you spawn a secondary thread, you
must create your own autorelease pool
as soon as the thread begins
executing; otherwise, you will leak
objects. (See “Autorelease Pools and
Threads” for details.)
Btw, you're calling pushViewController: from a background thread. This is bad.
You should only do things to the UI - like pushing view controllers and changing UI items - from the main thread. If you don't, things break.
See the Cocoa Fundamentals Guide section titled "Are the Cocoa Frameworks Thread Safe?": it says "All UIKit objects should be used on the main thread only."

uiimagepickerview controller creating memory leaks in iphone - why?

uiimagepickerview controller creating memory leaks in iphone - why?
Try to implement ui image picker view controller in your application & debug it.
You will find memory leaks in your application.
Why ui image picker view controller creates memory leaks.
-(void)addPhotos:(id)sender
{
if(imagePickerController==nil){
imagePickerController=[[UIImagePickerController alloc]init];
imagePickerController.delegate=self;
imagePickerController.sourceType=UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePickerController.allowsImageEditing=YES;
imagePickerController.navigationBar.barStyle=UIBarStyleBlackOpaque;
}
[self.navigationController presentModalViewController:imagePickerController animated:YES];
}
dealloc of my view controller.
- (void)dealloc {
if(PhotoDateArray!=nil)[PhotoDateArray release];
if(imagePickerController!=nil) [imagePickerController release];
if(objDetail!=nil) [objDetail release];
if(Picimage!=nil) [Picimage release];
if(mySavePhotoController!=nil) [mySavePhotoController release];
if(LoadingAlert!=nil);
[super dealloc];
}
Video link explaining how I am getting the memory leak in it..
http://www.yourfilelink.com/get.php?fid=508534
Even though you have the nil check, it's still possible to leak memory. I think what is happening here is that you are calling alloc / init multiple times, but only releasing once. My guess it that addPhoto: is wired up to some button click, dealloc would only be called once when the delegate is trying to destroy. This creates a situation like this:
button click
alloc / init
button click
alloc / init (memory leak on first alloc'd picker)
close window
dealloc (free second alloc'd picker)
A better way might be the way Apple does it in the PhotoLocations and iPhoneCoreDataRecipes examples:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
[self presentModalViewController:imagePicker animated:YES];
[imagePicker release];
Then listen for the didFinishPickingImage and imagePickerControllerDidCancel messages to your delegate and a call to [self dismissModalViewControllerAnimated:YES]; in both places should suffice.
I dont know about the rest of the code, but do you ever have a release?
[imagePickerController release]
UIImagePickerController loads and initializes PhotoLibrary.framework the first time it is shown. This memory won't be reclaimed until your application is closed.
(the code you posted doesn't appear to have leaks as-is, but that doesn't mean it won't interact with the rest of your application in a way that causes them)
I can explain this because I was having the same problem.
Don't test memory on the simulator!
If you test the apple code on a device the memory problem disappears.
I was having a memory alloc leak which I found in Instruments. All I was doing was opening and closing the image picker (open/cancel) and using Apple code, my code and other people's code, just like yours above.
All were showing the allocation going up and up each time, as if the picker was not being released. If you tried to release it, it would crash (over released).
Then I found a really helpful web page which basically stated:
"This doesn't happen when testing on the device"
So I switched from the simulator and ran the tests on the device. Lo & behold there was no allocation increase and it behaved normally.
This however is totally evil and now we can place no trust in the simulator to do a reliable job.
I want to add this to save people, the time, pain and bewilderment of wondering wtf is going on!