NSMutableArray - removeallobjects produces a leak - iphone

I have a mutableArray that I fill up with objects. When I try to refill the array, I first use removeAllObjects - which produces a memory leak...
The properties of the object are synthesized, retained and released on dealloc.
The Array is initialized on viewDidLoad like this:
theArray = [[NSMutableArray alloc] initWithCapacity:10];
... and it's retained and synthesized. (#property (nonatomic, retain) NSMutableArray *theArray)
I'm adding the objects in a while-loop like this:
myObject *theObject = [[myObject alloc] init];
theObject.someProperty = #"theprop";
[theArray addObject: theObject];
[theObject release];
then on the next call of the method, I remove all objects like this:
[theArray removeAllObjects];
That's where the leak occurs. If I comment this line out, the leak doesn't appear. So I guess I'm doing something wrong in my object?

Seems like the problem is solved...
a) I didn't realize, that when I use instruments, the app isn't compiled before launch - thus, some of the changes I made were not taking into effect, when using instruments. So now I first build and run after a change and then run it in instruments.
b) thus, I don't really know what solved the problem. But it might be that I had the dealloc-method in my object wrong.
I was using:
[super dealloc];
[myProperty release];
instead of the other way around:
[myProperty release];
[super dealloc];
Thanks for the help, though!

Does myObject have any retained properties? If so, are you setting them to nil in the dealloc message? If not, when it is dealloced it won't release the objects that its properties are set to.

Related

Iphone Right way to set a property

i have the following code in .h:
#property (nonatomic, retain) NSArray *arrayData;
And in the .m in method initWithNibName:
self.arrayData = [NSArray arrayWithObjects:#"Usuario:",#"Password:",nil];
is it right in order to call
[self.arrayData release]
safely in order to release the object?
No, it is not correct to call release on your property. The problem with it is, that you release your property, it will get deallocated, but you didn't set your pointer to nil, so somebody might send a message to your property and get a crash.
What you can do is the following:
self.arrayData = nil; ( which will release the previous saved instance, and set the property to nil)
[arrayData release]; arrayData = nil; (here you are accessing your ivar instead of your property; setting your ivar to nil is a precaution)
[self->arrayData release]; self->arrayData = nil (this is exactly the same as #2)
Hope this helps.
You need to call:
[arrayData release]
Calling [self.arrayData release]; will not have the effect you want it to in either case.
If you're wondering why this is, check this question out: difference between [self.property release] and [property release]
A)
it is a bad idea to do this in your initializer (e.g., initWithNibName:bundle:)
self.arrayData = [NSArray arrayWithObjects:#"Usuario:",#"Password:",nil];
use this instead:
arrayData = [[NSArray alloc] initWithObjects:#"Usuario:",#"Password:",nil];
you should not call these accessors (properties) in initializers or dealloc.
B)
is it right in order to call
[self.arrayData release]
no. in many cases (assuming you implement some of the properties you've declared), you may not be returned the the ivar. you may receive a copy, a placeholder object, or a subclass may have chosen to re-implement the accessors (as some examples). in these cases, it's easy to over-release or over-retain (resulting in evil stuff, like leaks and crashes).
this is typical:
self.arrayData = nil;
unless you are in dealloc of the object which declared the ivar:
- (void)dealloc {
[arrayData release], arrayData = nil;
[super dealloc];
}

iOS - resetting NSMutable Array causes crash

I have an NSMutableArray I'm trying to reload after an async call. The first time it loads like this:
self.sessionProcList = [NSMutableArray arrayWithArray:[result records]];
After the user does some interaction, the same line will be reached to reload the NSMutableArray. This causes the crash
Header file has:
#interface...
NSMutableArray *sessionProcList;
... }
#property (nonatomic, retain) NSMutableArray *sessionProcList;
Say you do:
NSMutableArray *a = [NSMutableArray arrayWithObject: [[NSObject alloc] init]];
NSObject *o = [a objectAtIndex: 0];
[a removeAllObjects];
[o description]; // *BOOM*
The above will [generally -- sometimes not but only by coincidence] crash because o has been deallocated by the time the description method is invoked.
If you have a reference to an object in an array, but have not retained said reference, then said object may be deallocated out from under you when you empty the array.
(And nonatomic vs. atomic is irrelevant.)
If I had to guess, I would say that elements in that array are being referenced from somewhere else. Resetting the array causes the items using the references to crash.
I would check your application for other variables, properties, or UI elements using those variables that have not been release before resetting it.
Because arrayWithArray is a convenience method it gets initialised with an autorelease flag.
You haven't mentioned what the crash / error message is but I am guessing your NSMutableArray is getting released before your second iteraction with it starts.
Try and retain the array for however long you need it with:
self.sessionProcList = [NSMutableArray arrayWithArray:[result records]];
[sessionProcList retain];
And then release it when you're done with it:
[sessionProcList release];
I hope it helps.
Rog

Is this a memory leak?

I have the following 2 code snippets.
Assume I have a Parent class and in Parent.h class I have
#property (retain) NSMutableArray *childrens;
and I have synthesize it in the .m file correctly.
assume in Parent.m file
-(void) dealloc
{
[childrens release];
[super dealloc];
}
In another class I declare like this.
1.
Parent *p = [[Parent alloc] init];
p.chidlrens = [[NSMutableArray alloc] init];
// do some other stuff
2.
Parent *p = [[Parent alloc] init];
NSMutableArray *childArray = [[NSMutableArray alloc] init];
p.childrens = childArray;
[childArray release];
From above 2 methods is there a leak in method 1?
Yes, there is a leak in method 1. You alloc a NSMutableArray but don't release it.
While not answering your question, I'd recommend having Parent init and alloc the array in it's Init method, so your code elsewhere doesn't have to worry about checking if it's already created and doing it. Then you don't need to have the classes that use Parent worry about Parent's memory management - Parent can do it.
the general rule is to release anything your doing alloc, init on.
but do a build + analyze to get some 'potential' leaks.
if you want to be 100% sure, run it though leaks
To check where is leakage you can without somebody help. For example, use any plugins for that. I use deleaker and know exactly where is a memory leak.

Why does my NSMutableArray cause a leak?

This is what Instruments is pointing to.
students = [[NSMutableArray alloc] initWithArray:[course.students allObjects]];
I'm releasing the array in dealloc. In the rest of my code I'm only calling the array and I'm not alloc'ing it again. I've also tried filling the array via fast enumeration and I get the same problem.
Just to be sure, add an autorelease to it, like
students = [[[NSMutableArray alloc] initWithArray:[course.students allObjects]] autorelease];
Then see what happens. (maybe assign it to self.students btw, and make that a retained property using #property (nonatomic,retain))

How do I set an array with another Array?

#property (nonatomic, retain) NSMutableArray *filteredListContent;
----
#synthesize filteredListContent;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSMutableArray *test = [[NSMutableArray alloc] init];
[test addObject:#"test string"];
[filteredListContent addObjectsFromArray:test];
NSLog(#"%#", test);
NSLog(#"Filtered Array is %#", filteredListContent);
[window makeKeyAndVisible];
}
My Log for test shows 'test string' but 'Filtered list array is (null)'
How do I set the array 'filteredListContent' with the array test...
What am I doing wrong? :-(
Are you creating and initializing filtersListContent anywhere? Your code looks right, that should work.
You should also make sure to release your test variable, you have a memory leak here.
You have to actually create filteredListContent, say with [[NSMutableArray alloc] init]. The error you are getting is that you are calling a method, -addObjectsFromArray:, on an object that is still nil: never created. As such, it just returns nil, and the list is never filtered.
filteredListContent is a pointer to a NSMutableArray, it does not have any memory assigned to it, as a result you cannot call methods on it. The compiler does not generate an error because you are passing a message to nil which is perfectly alright.
Thanx for that.
so I changed the line...
[filteredListContent addObjectsFromArray:test];
to read...
filteredListContent = [NSMutableArray arrayWithArray:test];
This done it. I think I understand it now, though I declared it, I never created it...
Thanx.