谁能解释一下这个保留计数代码中发生了什么?

发布于 2024-11-02 18:43:10 字数 512 浏览 8 评论 0原文

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);
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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黄昏下泛黄的笔记 2024-11-09 18:43:10

您的问题是您期望 retainCount 有用。

事实并非如此,您应该忘记 retainCount 存在

但发生的情况是这样的:

NSMutableString *ms = [[NSMutableString alloc]init];

您创建了一个可变字符串。 您拥有它并负责释放

[ms appendFormat:@"element %ld",1];
[ms appendFormat:@"element %ld",2];

您将一些数据附加到字符串中。所有权没有变化。

NSMutableString *ms2 = [ms mutableCopy];

您创建该字符串的副本。 您拥有该副本并负责释放

NSValue *sw = [NSValue valueWithNonretainedObject:ms2];

您将指向字符串副本的指针存储在NSValue中。您不拥有 NSValue (因此不必释放它),并且由于您使用的是 NonretainedObject: 变体, ms2 对象的所有权不变。

NSMutableArray *a = [NSMutableArray array];

您创建一个可变数组。你不拥有它。

[a addObject:ms];

您将一个对象添加到数组中。 数组现在也拥有该对象

[a addObject:sw];

您将一个对象添加到数组中。 数组现在拥有该对象(您仍然不拥有它)

因此,在此代码的末尾,您拥有:

  • ms
  • ms2

这意味着为了使您的代码正确,您还应该:

[ms release];
[ms2 release];

编辑:

您如何知道何时“拥有”一个对象以及何时不“拥有”一个对象?这非常简单:

  • 如果您通过以单词“alloc”开头的方法检索对象,或者...
  • 如果您通过以单词“new<”开头的方法检索对象/code>”或...
  • 如果您通过包含单词“copy”的方法检索对象,或者...
  • retain”该对象

如果您显式 请记住:New-Alloc-Retain-Copy(“NARC”)。如果您满足这四个条件之一(并且文档/方法声明没有另外说明),那么您“拥有”该对象,并且必须通过调用 releaseautorelease< 来放弃该所有权/code> 在该对象上。

这一切都在内存管理编程中非常清楚地阐述指南

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.

一枫情书 2024-11-09 18:43:10
  1. 创建一个您拥有的新的可变字符串 ms(如果您“分配”它,您就拥有它*),因此它以保留计数为 1 开始(并且不是“自动释放”),
  2. 对于 ms2 也是如此(如果您创建它)通过“复制”你拥有它*)
  3. ms2 被 NSValue 的 sw 包装,但 sw 不想保留 ms2 (valueWithNonRetainedObject),因此 ms2 的保留计数不会增加
  4. ms 和 sw 被添加到可变数组 a 中。数组始终保留其元素,因此 ms 和 sw 的保留计数加一 - 但 ms2 的保留计数不会增加,因为它不是数组的元素(而是 NSValue sw 的元素)

*) 请参阅 内存管理规则

  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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文