开发者

Can anybody explain me what is happening in this retain count code?

开发者 https://www.devze.com 2023-02-28 06:51 出处:网络
NSMutableString *ms = [[NSMutableString alloc]init]; [ms appendFormat:@\"element %ld\",1]; [ms appendFormat:@\"element %ld\",2];开发者_开发百科
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.


  1. 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")
  2. the same holds true for ms2 (if you create it through "copy" you own it*)
  3. 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
  4. 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

0

精彩评论

暂无评论...
验证码 换一张
取 消