Memoryleak on navigation of viewcontroller in iOS5 - objective-c

I have done navigation one viewcontroller to another, But when I done navigation multiple times my application shows memory leak, I run application with NSZombie detection ,that shows "Insufficient task_for_pid privileges (LeakAgent)". It is ARC enabled(xcode 4.2, iOS5) Please help.......
My code is here:
self.locationMapDetail = [[LocationMapDetail alloc] init]; //14.3% Leak
self.locationMapDetail.objItem = [self.parsedItems objectAtIndex:selectedIndex]; //5.7% Leak
[self.navigationController pushViewController:locationMapDetail animated:YES]; //80.3% Leak
self.locationMapDetail = nil;
self.locationMapDetail.objItem = nil;

You must release the objects before making it nil.Something like
[self.locationMapDetail release];
self.locationMapDetail = nil;
You should do it for all the objects that you allocate , if you are not using ARC.
In case of strong pointers even if you release the object you might not release it efficiently or it may be only virtually released as a strong pointer can be released only if all the references of the strong pointer has been released.It happens because sometimes the target may have strong pointer reference back to the declared variable.
Also Please mention the method you are using to create your variables..(viewDidLoad or viewWillAppear).It is advisable to create it in viewDidLoad.

I have also faced the same issue, It took me almost 2 days to resolve the issue. Finally got the solution.
Make sure that your profile scheme is in DEBUG mode instead of RELEASE. This will solve the issue.

Related

Objective-c example code that intentionally messages a deallocated object

I'm new to objective-c and xcode and an app I'm currently writing is receiving the infamous EXC_BAD_ACCESS error.
Almost everybody recommends starting to solve the problem using NSZombies. I think I have NSZombies working but xcode isn't giving me an alert about a zombie being messaged when my app crashes.
Before I move on with my debugging, I'd like to run some code that should for sure result in a message being sent to a zombie (de-allocated object).
What is a simple code snippet where a message is sent to a deallocated object, causing a scenario where NSZombies should alert me?
For non-ARC code:
- (IBAction) messageZombie:(id)sender {
id a = [[NSObject alloc]init];
[a release];
NSLog(#"%#", [a description]);
}
This will give you EXC_BAD_ACCESS with Zombies off, and a "message sent to deallocated instance" message, with Zombies enabled.
If your project is using ARC, then it's a bit harder to reliably-cause messages to de-allocated objects (that is the point of ARC, after all).
This works:
- (IBAction) messageZombie:(id)sender {
id a = [[NSObject alloc]init];
id __unsafe_unretained b =a;
a=nil;
NSLog(#"%#", [b description]);
}
It's probably not very similar to what your actual code is doing, because who the heck uses __unsafe_unretained, anyway? But if you just want to make sure that you've got NSZombies turned on properly, this should be a reasonable test case.
If you're looking for suspicious places in your code, then for sure look for __unsafe_unretained pointers, though you won't find any*, and double-check that the right casts are used for CoreFoundation objects that are casted to Cocoa objects.
* If your project needs to support OS X versions before 10.7, or iOS versions earlier than 5.0, then you can't use __weak pointers, so in that sort of project, you'd expect to find __unsafe_unretained used more often.
You could create a CF object, bridge it to an Objective-C object, then release it and try to use the bridged object. I think you have to use __bridge to get this to behave the way you want.

ARC: Memory does not get reclaimed?

I am working on an iPad (only) app and I stumbled across a weird problem. The app gets terminated after a memory warning on iPad 1 but works fine on iPad 2.
I am using ARC and targeting iOS 5. I use nibs and most of my assets are displayed using UIImageViews. I also have a few hundred buttons and plenty of gesture recognizers... I re-watched the WWDC11 videos (sessions 323 and 322) on ARC and I don't seem to be doing anything special.
The app is UIImage intensive, I am doing lots of animations using UIImage. I am however using the initWithContentsOfFile constructor rather than the imageNamed call. I'm trying to prevent the images from being cached by the system.
I'm also using GCD to schedule sound effects and to animate views. I'm always doing this on the main thread.
The app uses a UINavigationController that never has more than 1 UIViewController on it's stack. I can confirm that this is true because the didReceiveMemoryWarning only gets called on the current view controller (I'm logging the call).
The thing I don't understand is why Instruments is reporting high numbers (as if the view controllers don't get deallocated) in both the Allocations and VM Tracker instruments. The Allocations instrument shows a small drop when I navigate from one view controller to another (which is what I expect) but the VM Tracker Instrument shows that the Dirty Size is not dropping when I do the same thing. Eventually the app uses too much memory and gets terminated (on iPad 1). When I get memory warnings on the iPad 2 the app does NOT get terminated though...
It feels as if my images, sounds or views don't get destroyed and the memory does not get reclaimed... My object hierarchy is very basic and there should not be any retain cycles of any sort. I don't even have simple delegates...
Do you have any suggestions? I really don't want to release this app only for the iPad 2 or newer... It's an app for kids and it would be a pitty... I'd be so much happier to learn that I'm doing something wrong, as I really want to make sure this app is the best it can be...
Cheers,
Nick
There are ways to say, 'optimise' your objects by setting their properties to nil when certain things aren't needed -- so while you can't write a dealloc method anymore, you can do self.object = nil (when pertinent) which ends up doing something like this in a non-ARC world for an 'retain' (i.e., strong) property:
- (void)setObject:(id)newObject
{
[object release]; // send release message to current object
object = newObject; // set reference to newObject
[object retain]; // send retain message to newObject
}
Now while in ARC you don't/can't write retain/release yourself in your code, the compiler inserts these calls for you, meaning that in practise, setting a property to nil would do this in the above example:
[object release]; // send release message to current object
object = nil; // set reference to nil
[object retain]; // send retain message to nil (no effect)
Moreover, this is just the tip of the iceberg -- you should make sure that there are no retain cycles in your code, which could be resulting in objects leaking without recourse to their destruction. This means, that there may be places where you're using strong references to a property (i.e., an object), when you should be using a weak property. The difference being, that strong references are retained, and weak references are assigned, the former having its retainCount incremented and the latter resulting in a property assignment that looks like this if handwritten:
- (void)setObject:(id)newObject
{
object = newObject;
}
I don't like answering my own question but I figured it could be helpful to future googlers. I implemented my own UIImage based animation and I no longer use the animationImages property. Turns out my memory issues are now gone as I no longer need to store all the images in memory and I load them as they are required using a timer.
I actually think that rolling out a custom animation is beneficial since it allows for callbacks and more powerful customisation options.
Once I'm happy with it and I feel like it's ready to be shared I will post the class(es) on GitHub.

Large retain count with a recent created object. Objective-C

I'm getting an strange case of excessive retain counts for a view controller that I'm loading when a button is pushed.
This is the code:
-(IBAction)new
{
if (!viewSpace)
viewSpace = [[ViewSpace alloc] initWithNibName:#"ViewSpace" bundle:nil];
viewSpace.delegate = self;
viewSpace.view.frame = CGRectMake(0, 0, viewSpace.view.frame.size.width, viewSpace.view.frame.size.height);
[self presentModalViewController:viewSpace animated:YES];
NSLog(#"Count Retain: %d",[viewSpace retainCount]);
}
-(void)viewSpaceWasDissmissed:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
[viewSpace release];
NSLog(#"Count Retain: %d",[viewSpace retainCount]);
}
When the IBAction New is executed first time, the retain count is 5 when just is created. (It must be 1).
When the ViewSpace object must be unload calls viewSpaceWasDismissed function in order to remove the modal view and release the previous object.
The problem is that never the retain count reach 0 and the dealloc method of ViewSpace never is called causing memory leaks.
My question is how is possible that a recently created ViewController have 5 retains? I made sure that is never created before.
Thanks.
Cocoa is probably retaining the view controller 4 times internally for reasons of its own. This isn't a problem.
More generally, the -retainCount method is useless for reasons like this, and you should never call it. It will not help you, and it will confuse you.
To debug your leak, I suggest using the leaks Instrument, inspecting the object, and analyzing where each retain and release is coming from to determine whether any are incorrect.
Check the documentation for -retainCount. I believe it says that you should not be calling it yourself - you just need to take care of any retains that you cause, and don't worry about the 'actual' retain count.
You're doing two things wrong here:
The Current view controller retains the modally presented view controller and releaseds it when it is dismissed. So you should release viewSpace after it is presented, and you don't need the release message in the dismissModalViewController method. As an aside ViewSpace is a poor name for a view controller. I had to read to the line where you are presenting it as a view controller before I knew it was a view controller. I think ViewSpaceController is a more descriptive name.
You are using retainCount which is always a bad idea. All that matters is that in your new method you created an owned object (with the alloc) and you balanced that ownership with a release (or at least you will do when you put in the correction I suggested in point 1) That's it. You took ownership of an object and you released it. The retainCount method tells you absolutely nothing that can be of any use to you. Don't do it. Just balance ownerships with release, and that is all that matters.
I'm not 100% sure of every count but here are some:
Instantiation - 1
NIB - 1+
Strong Properties (1+)
Additionally any properties that list it as a strong property (in ARC).
I noticed that when you launch a nib and you use components of the controller in the nib design, it will increase reference counts (in a strong manner) on the controller instance.

Allocating and releasing memory in iPhone Xcode 3.2.5, iOS 4.2.1

I am having a strange issue with tableview showing (null) when another ViewController comes and goes. I traced it down to the place that it reads the data to display to the tableview and found that it read null for data. To debug this, I need to understand how memory management really works for iPhone. I used the following code in my application delegate to create an array of objects. This was from a sample code which I modified for my app. My question is when one creates an array like this, would the [tempArray release] actually release the array that was just created?
//Initialize the hardware array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.hardwareArray = tempArray;
[tempArray release];
This type of code seems to be very common for iPhone. The tutorials keeps saying for example, now that you passed the data to the controller you can release it. But my C and C++ experience tells me, if you release the memory it would be gone, and if its address is sitting someplace on the stack, its no good. Is the data being copied to another place rather than address being passed?
Also when releasing memory in a set routine like the one below, should I be checking to see if the modleName is not nil before releasing it. What happens if one released modelName that is already nil?
-(void) setModelName:(NSString *)newValue {
self.isDirty = YES;
[modelName release];
modelName = [newValue copy];
}
My question is when one creates an array like this, would the [tempArray release] actually release the array that was just created?
If the #property of the object is assign it would get released. But usually you use retain or copy as #property. And if the property is retain, the setter you call with self.hardwareArray = ... (ie [self setHardwareArray:...]) will retain the object. If the property is copy it will create a new object that is retained already.
Also when releasing memory in a set routine like the one below, should I be checking to see if the modleName is not nil before releasing it. What happens is one released modelName that is already nil?
In objective-c messages sent to nil are perfectly legal. No need to worry, no need to check for nil.
If you release an instance variable outside of dealloc you should set it to nil after releasing it.
release doesn't do what you think - it isn't equivalent to free() or delete and doesn't cause the memory to be gone.
It really is important to fully understand the few simple memory management rules before you do any coding. It's not difficult, the best resources are the Apple Developer Guides, like this one
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html%23//apple_ref/doc/uid/10000011i

Using dismissModalViewControllerAnimated won't free any memory

I have a very simple code to show a modal controller (nextController is a class member):
nextController = [[InstructionsScreen alloc] initWithNibName:#"InstructionsScreen" bundle:nil];
[self presentModalViewController:nextController animated:YES];
[nextController release];
And then when the controller should hide:
[self dismissModalViewControllerAnimated:YES];
nextController = nil;
All works good as expected, but when I run instrument Object Allocations it shows that after dismissing the modal controller the memory it allocated is not freed. This becomes a problem because when I show several controllers the memory is over ...
Can anybody give me some clues ? Clang doesn't see any problems, so I'm stuck hitting the memory limit, because the memory of the dismissed controllers won't get released.
EDIT: What I discovered up to now is that it seems to be a leak somewhere in Apple's stuff. Way to reproduce: XCode -> create new project with the template "Utility application". Don't write any code yourself. Just create a new utility application and run it with "Object allocations", choose to see "Created & Still living". Now flip the modal controller few times - you'll see the allocated memory only grows and grows every time the modal controller is appearing and when it's disappearing too ...
There is no leak in the code you show as far as I can see. There could be a leak in InstructionsScreen that would prevent it being deallocated.
I think it's worth running the Static Analyser to see if it finds a leak.
The leak in the Apple template code is interesting. It could be that there is a leak. It seems unlikely but obviously it's not impossible. I would say that it's more likely that it's a false-positive in Instruments, which is why I'd suggest using the Static Analyser.
(You might want to raise a bug report about the leak.)
Modal views are not subviews of the calling view but are instead subview of the apps window and are retained by the window itself. You generally you do not retain a reference to them in the controller that calls them. Instead, evoke the modal view and then have it communicate with the controller by defining the controller as the modal view's delegate.
I think that if you use synthesize to create the accessor for a nextController property defined with retain, then the accessor will retain any object assigned to the property. Simply setting the value to nil will not release the object unless the accessor is set up to do that and I don't think the autogenerated ones do.
You will expressly have to call release before setting to nil.
If this doesn't work, post the code for your definition of the nextController property.