【问题标题】:Retain Count Of Objects保留对象数
【发布时间】:2017-08-26 21:51:34
【问题描述】:

我在 iOS 的 MRC 中有一个查询,我有点困惑。假设我有两个相同类型的对象 ObjectA 和 ObjectB,保留计数低于

  1. ObjectA:保留计数为 1
  2. ObjectB:retin 计数 0

现在我在做手术

ObjectB = [ObjectA retain];

谁能告诉我 ObjectA 和 ObjectB 的保留数量是多少?

据我所知,保留 ObjectA = 2 & ObjectB = 1 的数量。

如果我错了,请纠正。如果我们要执行复制操作,那么应该保留什么。

【问题讨论】:

  • 你为什么使用MFC,你为什么使用Objective-C?你应该在 ARC 和 Swift 中进行新的开发。
  • @DuncanC 绝对不在 Swift 中。而且我确信他没有使用 Microsoft Foundation Classes。
  • 抱歉,应该是“MRC”,而不是 MFC。 :)
  • clang 称它为 MRR,但我也更喜欢 MRC。

标签: ios objective-c


【解决方案1】:

首先你要明白,objectAobjectB不是(Objective-C)对象。它们是对对象的引用。 (对象有保留计数,而不是对对象的引用。)

所以,你的情况是正确的:

  • objectA 指向一个 RC 为 1 的对象。
  • objectB 指向一个 RC 为 0 的对象。

第二句话是一个悖论:永远不会有 RC 为 0 的对象,因为达到 RC 0 会释放对象。所以没有对象了。 (实际上,永远不会达到 0 的 RC,因为当 RC 为 0 时,对象会被释放。但这是一个实现细节,因此并不重要。)

声明……

objectB = [objectA retain];

…增加对象的RC*,objectA指向。 -retain 的返回值是接收者指针 (objectA) 的值。然后将此引用分配给objectB。因此objectB——仍然是一个引用——指向同一个对象,objectA指向。由于 RC 归对象所有,因此只有一个对象和一个 RC。是2。

备注* 即使有文件证明-retain 会增加 RC,但并非总是如此。有些物体具有永恒的生命周期,具有虚拟标记 RC。但是,我会保持答案简单,因此我们假设每次执行 -retain 都会增加 RC。但是试试这个:

    id ref = @"RC";
    NSLog(@"%lu", [ref retainCount]);
    [ref retain];
    NSLog(@"%lu", [ref retainCount]);

你得到:

2017-04-01 22:09:21.214 reftest[74967:8550738] 18446744073709551615
2017-04-01 22:09:21.215 reftest[74967:8550738] 18446744073709551615

增加了什么?没有。

但是出于同样的原因,您永远不应该考虑 RC 的绝对值(“1 的 RC”),而是在源代码中更改某个位置的值:保留后,RC 通常大于1 比以前多了。发布后,RC 通常小于 1。计算绝对值必须考虑对该对象的所有强引用,这是不可能的。这是没有意义的,因为它是 RC 的力量,你认为引用引用而不是所有引用在一起。

【讨论】:

  • 您的回答很好、清晰且易于理解,直到您到达“备注”位。我对 MRC 有非常深刻的理解,但我无法真正理解那段内容。
  • @Amin 谢谢,你能解释一下你的Remark吗?我无法获得?
  • @DuncanC Gagan_iOS:你不能说一个对象有一个特定的 RC。要进行这样的计算,您必须知道对该对象的 所有 强引用,包括可能存在的内部引用。这是不可能的,也没有任何意义,因为 RC 的优势在于您可以通过引用在本地引用 RC。 (你释放,你保留。你不做整体计算。)相对写RC是一个好习惯,i。 e. +1, +2, ... 而不是 1, 2, ... 来表达这一点。数学上是一样的。
  • 可能第一句话你没看懂。试试这个:打印@"RC"的引用计数。 (这是一个字符串对象。)然后保留它并再次打印它。你看到了非凡的价值吗?
  • 添加了一些解释。并将“绝不能”更正为“不是”。 (我的错,在翻译中迷路了。)
【解决方案2】:

你的问题真的没有意义。

首先,关于变量名的评论:您应该使用以小写字母开头的变量名。

如果您在 ObjectA 中有一个对象,在 ObjectB 中有一个对象,并且 ObjectB 的保留计数达到零,则它会立即被释放,并且不再存在。 ObjectB 现在是“僵尸”(指向已释放对象的指针。) 如果您在 ObjectB 的保留计数达到零后尝试对其执行任何操作,您可能会崩溃,或者系统可能会在该内存中存储不同的对象,并且您的代码实际上可能指向完全错误的对象。

当你执行该行时:

ObjectB = [ObjectA retain];

...那么变量 ObjectB 现在也指向 ObjectA,并且您已将 ObjectA 对象的保留计数增加到 2。(ObjectB 和 ObjectA 现在是同一个对象,保留计数为 2。)

【讨论】:

  • @Ducan,感谢您的宝贵回答。
猜你喜欢
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
相关资源
最近更新 更多