Can anybody explain me what is happening in this retain count code?
NSMutableString *ms = [[NSMutableString alloc]init];
[ms appendFormat:@"element %ld",1];
[ms appendFormat:@"element %ld",2];开发者_开发百科
NSMutableString *ms2 = [ms mutableCopy];
NSLog(@"ms retain count:%lu",ms.retainCount);
NSLog(@"ms2 retain count:%lu",ms2.retainCount);
NSValue *sw = [NSValue valueWithNonretainedObject:ms2];
NSMutableArray *a = [NSMutableArray array];
[a addObject:ms];
[a addObject:sw];
NSLog(@"ms retaincount %lu",ms.retainCount);
NSLog(@"ms2 retaincount %lu",ms2.retainCount);
Your problem is that you're expecting retainCount
to be useful.
IT IS NOT, AND YOU SHOULD FORGET THAT retainCount
EXISTS
But here's what happens:
NSMutableString *ms = [[NSMutableString alloc]init];
You have created a mutable string. You own it and are responsible for releasing
it
[ms appendFormat:@"element %ld",1];
[ms appendFormat:@"element %ld",2];
You append some data to the string. No change in ownership.
NSMutableString *ms2 = [ms mutableCopy];
You create a copy of the string. You own the copy and are responsible for releasing
it
NSValue *sw = [NSValue valueWithNonretainedObject:ms2];
You store the pointer to your string copy in an NSValue
. You do not own the NSValue
(and thus do not have to release
it), and since you're using the NonretainedObject:
variant, the ownership of the ms2
object is unchanged.
NSMutableArray *a = [NSMutableArray array];
You create a mutable array. You do not own it.
[a addObject:ms];
You add an object to the array. The array now also owns the object
[a addObject:sw];
You add an object to the array. The array now owns the object (you still do not own it)
So at the end of this code, you own:
ms
ms2
This means that for your code to be correct, you should also have:
[ms release];
[ms2 release];
Edit:
How do you know when you "own" an object and when you do not? It's pretty simple:
- If you retrieve an object via a method that begins with the word "
alloc
" or... - If you retrieve an object via a method that begins with the word "
new
" or... - If you retrieve an object via a method that contains the word "
copy
" or... - If you explicitly "
retain
" the object
Just remember: New-Alloc-Retain-Copy ("NARC"). If you satisfy one of those four conditions (and the documentation/method declaration doesn't say otherwise), then you "own" the object and must relinquish that ownership by invoking release
or autorelease
on that object.
This is all very plainly laid out in the Memory Management Programming Guide.
- a new mutable string ms is created that you own (if you "alloc" it you own it*) hence it starts with a retain count of one (and is not "autoreleased")
- the same holds true for ms2 (if you create it through "copy" you own it*)
- ms2 is wrapped by sw of NSValue but sw does not want to retain ms2 (valueWithNonRetainedObject) hence the retain count for ms2 is not increased
- ms and sw are added to mutable array a. Arrays always retain their elements hence the retain count of ms and sw are increased by one - but not the retain count of ms2 since it is not an element of the array (but of the NSValue sw)
*) See the memory management rules
精彩评论