PDA

View Full Version : Problem Deleting From NSMutableArray




stadidas
Jan 16, 2007, 04:46 PM
Hi everyone.

I'm currently having a big problem with an NSMutableArray. At the moment I can addobjects to it, and they display in a NSTableView perfectly. When I remove them they are removed from the array, but when I try to open the sheet containing the tableView I get an error like this: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1)

If I then add another object to the array, the tableView works perfectly again. If I do not add another object and quit, I get this sort of error:
AssetMonitor [DEBUG](3206,0xa000ed88) malloc: *** Deallocation of a pointer not malloced: 0xbfffe270; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug

These are the methods I have for adding and removing:

- (void)addLog:(Log *)l
{
[logs addObject:l];
}

- (void)removeObjectIdenticalTo:(id)anObject
{
[logs removeObjectIdenticalTo:anObject];
}


I've been playing around for a few hours and haven't been able to come up with a fix. Any help appreciated with this one. Thanks.



kainjow
Jan 16, 2007, 05:57 PM
Please post more code. Sounds like you're not using memory management correctly. And remember arrays start with an index of 0 for their first item.

stadidas
Jan 16, 2007, 07:22 PM
I suspect it's memory management too.
Here are the methods from MyDocument:

- (void)add:(double)d:(NSString *)s
{
Log *l = [[Log alloc] init];
[l setDescription:s];
[l setAmount:d];
[self doAdd:d:s:l];
}

- (void)doAdd:(double)d:(NSString *)s:(Log *)l
{
[self addAmount:d];
[self addLog:l];
[tableView reloadData];

NSUndoManager *undo = [self undoManager];
[[undo prepareWithInvocationTarget:self]
removeLog:l];

[[undo prepareWithInvocationTarget:self]
subtractAmount:d];

if (![undo isUndoing]) {
[undo setActionName:@"Add to Balance"];
}
}

- (void)addAmount:(double)d
{
double tempBalance = [myBalance doubleValue];
double newBalance = tempBalance + d;
[detailsController setMyBalance:newBalance];
}

- (void)addLog:(Log *)l
{
[detailsController addLog:l];
}

- (void)removeLog:(id)anObject
{
[detailsController removeObjectIdenticalTo:anObject];
}

- (void)subtract:(double)d:(NSString *)s
{
Log *l = [[Log alloc] init];
[l setDescription:s];
[l setAmount:d];
[self doSubtract:d:s:l];
}

- (void)doSubtract:(double)d:(NSString *)s:(Log *)l
{
[self subtractAmount:d];
[self addLog:l];
[tableView reloadData];

NSUndoManager *undo = [self undoManager];
[[undo prepareWithInvocationTarget:self]
removeLog:l];

[[undo prepareWithInvocationTarget:self]
addAmount:d];

if (![undo isUndoing]) {
[undo setActionName:@"Subtract From Balance"];
}

}

- (void)subtractAmount:(double)d
{
double tempBalance = [myBalance doubleValue];
double newBalance = tempBalance - d;
[detailsController setMyBalance:newBalance];
}


The add: and subtract: methods are called from when a sheet is closed which passes the values. detailsController refers to an instance of a class called details which stores the NSMutableArray. The problem I described in the first post came from calling the add: method, and then hitting undo, which I expected to remove the instance of Log that had been stored.
Let me know if you want to see anything else.

kainjow
Jan 16, 2007, 08:19 PM
Well when you make your Log objects, you're leaking memory:

Log *l = [[Log alloc] init];
[l setDescription:s];
[l setAmount:d];
[self doAdd:d:s:l];

Should be

Log *l = [[Log alloc] init];
[l setDescription:s];
[l setAmount:d];
[self doAdd:d:s:l];
[l release];

(unless you were on 10.5 with GC enabled ;)

mduser63
Jan 16, 2007, 09:01 PM
I might point out that it's horrible programming style to use single character names for variables/arguments. Makes for really difficult reading later.

Note: If you're trying to make your code hard to read for some reason, ignore this.