MemoryLeak in iphone programming? - iphone

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;

Related

NSMutableArray automatically typecasting into NSArray

I created an NSMutableArray object by
NSMutableArray *array = [[NSMutableArray alloc]init];
and used method componentsSeperatedByString: as
array = [myString componentsSeperatedByString:#"++"];
but when I performed operation on array like,
[array removeAllObjects];
I got exception like "removeAllObjects unrecognized selector send to instance".
I solved this issue by modifying code like,
NSArray *components = [myString componentsSeperatedByString:#"++"];
array = [NSMutableArray arrayWithArray:components];
and I after that could perform operation like
[array removeAllObjects];
My doubt is why did NSMutableArray automaticaqlly converted to NSArray? How Can I avoid automatic type conversion like this, to prevent exceptions? Thanks in advance....
There is a mistake in your understanding of how Objective-C works. This line:
NSMutableArray *array = [[NSMutableArray alloc]init];
allocates and initializes the array, and the pointer array points to this object. Now, this line:
array = [myString componentsSeperatedByString:#"++"];
makes the array pointer to point to the new array returned by componentsSeparatedByString method. You loose the reference to your alloced and inited mutable array when you do this, and you create the memory leak if you don't use ARC.
This is happening because [myString componentsSeperatedByString:#"++"] returns an NSArray. You can try something like this:
array = [[myString componentsSeperatedByString:#"++"] mutableCopy];
or
array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
This is because – componentsSeparatedByString: returns a NSArray: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/componentsSeparatedByString:
Do something like:
array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
On the line
array = [myString componentsSeperatedByString:#"++"];
you are replacing the NSMutableArray you allocated with a new NSArray (and leaking your NSMutableArray. Try using this:
NSMutableArray *array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
It's not converted, the array pointer could be UIButton* if you write something like
array = [self likeThatButton];
where likeThatButton is your method returning UIButton*. As always in objective c, NSMutableArray *array means only the Xcode will try to analyze your code and suggest convenient warnings and code completion.
An NSMutableArray instance won't be converted automatically.
The method componentsSeperatedByString returns an NSArray-Object. You should get a compiler warning when assigning the return-value to a NSMutableArray-Pointer.

Why I can't access NSMutable Array in my method?

I try to add object to my NSMutable array in my method, but keep getting error. It works, if I add the object in init. It doesn't say that anything is wrong until I try to execute the code.
This is below the #import stuff where I declare two arrays:
NSMutableArray *actions1, *actions2;
This is in init:
actions1 = [NSMutableArray array];
Here I try to add 1 to the array:
- (void) storeAction:(int) action {
[actions1 addObject:#"1"];
}
The same code works in int as I said earlier.
I also would like it to store the int value declared "action", but this didn't seem to work either.
[addObject:#"%d", action];
[NSMutableArray array]; is returning an autoreleased object, by the time you try to access it, it is most likely deallocated already. Try [[NSMutableArray alloc] init]; instead. And than you should urgently check the memory management rules.
Try out this code
actions1 = [[NSMutableArray alloc] init];
Hope this helps.
Alternatively, in your header file:
#property(nonatomic, strong)NSMutableArray *actions1;
Then in the implantation file:
#synthesize actions1 = _actions1;
Then you can access your array as self.actions1.

Modifying an NSMutableArray inside a loop

I have an NSMutableArray filled with Task objects. I want to be able to delete those whose completed property are set to YES
NSMutableArray *allTasks = (NSMutableArray *)[[TaskStore defaultStore] allTasks];
NSMutableArray *completedTasks;
for (Task *task in allTasks) {
if ([task completed]) {
[completedTasks addObject:task];
}
}
[allTasks removeObjectsInArray:completedTasks];
While debugging I noticed that the completedTasks array is always empty. Why is this?
You forgot to initialize the completedTasks :
NSMutableArray *completedTasks = [NSMutableArray array];
You haven't initialized completedTasks. You need to add this:
NSMutableArray *completedTasks = [[NSMutableArray alloc] init];
You must initialize the array before you can use it, the initializing actually creates your array object -
To do this add This Line to create an autoreleased array (which means you dont have to release it)
NSMutableArray *completedTasks = [NSMutableArray array];
Or
NSMutableArray *completedTasks = [[NSMutableArray alloc] init];
But then you will have to release it by yourself [completedTasks release] when you are not using it any moere (unless you are using ARC).
This will create your array object.
Shani
from NSMutableArray documentation :
This method assumes that all elements in otherArray respond to hash and isEqual:.
You can try :
[allTasks filterUsingPredicate:[NSPredicate predicateWithFormat:#"completed = %#", [NSNumber numberWithBool:YES]]]

NSMutableArray removeAllObjects causing crash

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.

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.