NSMutableArray
and started to wonder about the lifecycle of items in a collection. I know that the collections in the Foundation library retain
objects when they're added and release
them when the collection dealloc
s itself, so it makes sense that calling removeObjectAtIndex:
or any of the other "remove" methods would also release
the object in question.The
removeObjectAtIndex:
method doesn't return the removed object to you -- if you want to hold on to it, you need to call objectAtIndex:
first. It also makes sense that you need to retain
the object you're holding on to. A quick inspection of my code showed that I wasn't doing that in at least one place, but my app wasn't crashing. This made me wonder if objectAtIndex:
was autoreleaseing the object it returned.A quick Google search turned up an entry in William Woody's Development Chaos Theory blog entitled The lifespan of an object owned by NSMutableArray, or why Objective-C annoys me and Java makes me happy.
The punchline?
MyObject *obj = [myMutableArray objectAtIndex:0]; [[obj retain] autorelease]; // before removeObjectAtIndex [myMutableArray removeObjectAtIndex:0]; UseMyObject(obj);
You need to
retain
the item before you remove it from the NSMutableArray
(and eventually release
or autorelease
it).The moral of the story:
NSString
literals are long lived and don't become invalid when a collection release
s them. If you build your NSMutableArray by doing something like this:NSMutableArray *myMutableArray = [[NSMutableArray alloc] initWithObjects:@"one", @"two", @"three", nil];
You will mask a lot of memory management problems.
1 comment:
Good points. Literal strings are never released:
NSString *str1 = @"i am a string";
NSString *str2 = [[NSString alloc] initWithFormat:@"i am a %@", @"string"];
NSLog(@"str1 %i", [str1 retainCount]);
NSLog(@"str2 %i", [str2 retainCount]);
[str1 release];
[str1 release];
[str1 release];
[str1 release];
[str1 release];
[str1 release];
[str1 release];
NSLog(@"str1 %i", [str1 retainCount]);
str1 will have a retain count of 1.
str2 has 2147483647, and it never changes.
Post a Comment