NSMutableArray removeAllObjects causing crash - iphone

I have a couple of arrays that I am trying to clear all objects from, but using removeAllObjects crashes the app and returns sigabrt. During my research I've found that although I am creating NSMutableArrays I could be creating an instance of a NSArray, but I am not sure if I am doing this or not... Here is everything I do to the arrays
ballArray = [[NSMutableArray alloc] init];
ballVelocityArray = [[NSMutableArray alloc] init];
[ballArray addObject:MyUIImageView];
[ballVelocityArray addObject:[NSValue valueWithCGPoint:myCGPoint]];
[ballVelocityArray replaceObjectAtIndex:SomeIndex withObject:[NSValue valueWithCGPoint:NewVelocity]];
[ballArray removeAllObjects];
[ballVelocityArray removeAllObjects];
That is everything I have done and I can't figure out why it keeps crashing... if there is only one object in the arrays it works fine, otherwise it crashes
Any help would be greatly appreciated!!

It's most likely because you are not managing memory correctly on one of the objects the array contains. When you remove an object from an array its retain count is decremented once.
You can put a break point on the line where you clear the array and use the debugger to see which object in there is invalid.

ballArray = [[NSMutableArray alloc] init];
ballVelocityArray = [[NSMutableArray alloc] init];
After allocating object you are also releasing the object in dealloc function or somewhere else check this.If you are doing so then I would like to inform you that
[ballArray removeAllObjects];
[ballVelocityArray removeAllObjects];
removeAllObjects is not only removing all objects of array but also release the array object from memory so if again you are releasing the array object the memory pointer will reach on -1 and the application will crash.
So, make sure that You have not to release array object it you are already using
[ballArray removeAllObjects];
[ballVelocityArray removeAllObjects];
functions.

Related

MemoryLeak in iphone programming?

Can any one help me to understand the problem in this image
As the analyzer says, you are allocating locs on line 647, using
NSMutableArray *locs = [[NSMutableArray alloc] init]; and not releasing it later in the block. You should release it or you can use convenience constructor to get the autoreleased array like this, NSMutableArray *locs = [NSMutableArray array];
I'd suggest you to still simplify your code to this,
NSMutableArray *annotations = (NSMutableArray *)[map annotations];
[annotations removeObject:[map userLocation]];
[map removeAnnotations:annotations];
You need to release locs at the very end. You have alloc'ed and init'ed it, giving it a reference count of 1, an then you should release it to change the reference count to 0. Refer to http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/ for more info.
You have initialize the locs array then you have to release that array before closing that function: [locs release];locs=nil;

memory leak situation in iphone

I have a memory leak when i call a method that return me a string----
the method definition is as follows
-(NSMutableArray *)read
{
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
//picking data from database here
return dataArray;
}
this show a big memory leak
i also tried--- NSMutableArray *dataArray = [[[NSMutableArray alloc] init]autorelease];
but this time leack checking process gets hanged
i also cannot release that array before return
please help
-(NSMutableArray *)read
{
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
//picking data from database here
return dataArray;
}
Anything that uses the method read will expect to get back an object it does not own. However, as written here, dataArray is still owned at the point of return. You can't release it because that might make it go away altogether. You must, in this instance autorelease the array. You can either do this:
-(NSMutableArray *)read
{
NSMutableArray *dataArray = [[[NSMutableArray alloc] init] autorelease];
//picking data from database here
return dataArray;
}
or this
-(NSMutableArray *)read
{
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
//picking data from database here
return [dataArray autorelease];
}
You say "leak checking process get hanged" but I'm really not sure what you mean by that. Whether it hangs, crashes or plays the Botswana National Anthem, you definitely need to autorelease the returned array and any other problem is actually a different problem. Possibly, you are forgetting to retain the data elsewhere.
Another answer more...
There are many conventions in cocoa/cocoa-touch, there is one of them that says that if a method has the prefix init then you will have the ownership of that object (hence you have to release it)
This is NOT your case, hence if you do:
DatabaseReader *dbReader = [[DatabaseReader alloc] init];
NSMutableArray *mutArray = [dbReader read];
[dbReader release];
you are NOT supposed to release mutArray. BUT, the object created HAS to be released by someone. So you can do as JeremyP wrote. alloc/init and put it into a autorelease pool inside read method implementation. Or, you can do:
-(NSMutableArray *)read
{
NSMutableArray *dataArray = [NSMutableArray array];
//IMPORTANT:
//Did you noticed that I am not using any method
//with init prefix for the creation of dataArray ?
//so I don't need to release by my self ;)
//picking data from database here
return dataArray;
}
Which is basically the same. ;)
Ownership of the returned object may be returned to the object that receives from this function. You may do some debugging with the object's retain count using something like this...
NSLog(#"Retain count: %i", [dataArray retainCount]);
Turn on the debugging console (Command + R in Xcode) to see the NSLog output.

Objective C two-dimensional array memory issues

I'm trying to declare a two-dimensional array as an instance variable in Objective C. I've got the NSMutableArray in the header (data), along with the #property (nonatomic, retain). In viewDidLoad: I have:
data = [[NSMutableArray alloc] init];
[data addObject:[[NSArray alloc] initWithObjects:#"Cheese", #"Meat", #"Veggie", nil]];
[data addObject:[[NSArray alloc] initWithObjects:#"Sandwich", #"Soup", #"Stew", nil]];
I can NSLog the array within the method and it is correct, however when I try to Log it from a separate method I get nothing (just "#"), and if I try to access with
NSInteger num = [[data objectAtIndex:component] count];
it crashes with no error in the log. I'm sure this is something to do with not allocating memory properly, however I am new to Obj C and haven't worked with a C-style language in many years. FWIW, I have tried many variants of this that all fail, including using NSArray instead of mutable, [NSArray arrayWithObjects] instead of [[NSArray alloc] initWithObjects], and every combination in between.
try creating the outer array like this:
self.data = [NSMutableArray arrayWithCapacity:2]; // assuming you're only adding 2 inner arrays.
The following may be a right way.
self.data = [NSMutableArray array];
[data addObject:[NSArray arrayWithObjects:#"Cheese", #"Meat", #"Veggie", nil];
[data addObject:[NSArray arrayWithObjects:#"Sandwich", #"Soup", #"Stew", nil];
Note that, as #jamihash commented above, you need self.data to properly retain the array. And, there is no need to alloc the NSArray which you are adding to data.
As a side issue, you're retaining the child arrays twice. They get retained when you add them to your NSMutableArray, so you should probably autorelease them on creation or create them with one of the NSArray methods that returns an autoreleased array.
Your code by itself shouldn't crash. You should look into where and when you release and retain the NSMutableArray. You could post more of the code and I'm sure somebody will spot the problem.

Should I release array returned from [NSMutableDictionary ValueForKey: ]

I have a NSMutableDictionary with the key being the first alphabet of the name of an object. The view is something like the 'Contacts' tab on iphone. Additionally user can select individual objects in the list.
In the code I find each selected object to process them further.
NSMutableArray *objectsToAdd = [[NSMutableArray alloc] init];
NSMutableArray *array = nil;
for (NSString *key in self.nameIndex) {
array = (NSMutableArray *)[searchedNameDictionary valueForKey:key];
for (Objects *eachObject in array) {
if (eachObject.objectIsSelected){
[objectsToAdd addObject:eachObject];
}
}
}
[array release];
-(void)dealloc()
{
[searchedNameDictionary release];
}
The app is crashing where I release searchedNameDictionary, with the message that the deallocated object is being referenced.
Now if in the code above, I remove [array release] the app works fine.
My question is does releasing 'array' is actually releasing the objects in searchedNameDictionary, which is what seems to be happening.
Would not releasing array cause memory leak?
You shouldn't release returned object unless they come from an alloc or copy method.
Returned objects are autoreleased otherwise, if you want to keep it around your should retain it right after receiving it.
array = (NSMutableArray *)[searchedNameDictionary valueForKey:key];
This returns an autoreleased object, thus you don't need to release it.
There are some other...issues with your code too, but mostly style things. Get rid of the [array release] and you're good to go as far as that issue is concerned.

Why Instruments report a leak?

I am developing an iphone app. Instruments reported a leaked object ServiceTypes. Below is the relevant code. Does anyone have any ideas? Thanks a lot for your help.
ServiceTypes *serviceTypes = [[ServiceTypes alloc] init];
if ([userConnection getServiceTypes:serviceTypes]) {
if ([serviceTypes.types length] > 0) {
NSArray *array = [[NSArray alloc] initWithArray:[serviceTypes.types componentsSeparatedByString: SERVICE_TYPE_DELIMITOR]];
serviceRequestTypes = [[NSMutableArray alloc] initWithArray:array];
[array release];
}
}
[[self typesTableView] reloadData];
[serviceTypes release];
It doesn't look like serviceTypes is being leaked. From the code you posted, serviceTypes is always released at the end of the method, and it doesn't appear to be retained anywhere in your sample. My question is: what happens inside getServiceTypes:. Does that method retain the serviceTypes parameter?
One more thing. If serviceRequestTypes is an instance variable (and it looks like it is), then you may be leaking memory by reassigning it without releasing the existing serviceRequestTypes object first. You should either rewrite serviceRequestTypes to be a property and use a synthesized accessor or make sure to release it every time before assigning. If its current value is nil, no big deal; the release message will simply be ignored. For example:
[serviceRequestTypes release];
serviceRequestTypes = [[NSMutableArray alloc] initWithArray:[serviceTypes.types componentsSeparatedByString:SERVICE_TYPE_DELIMITER]];