112

我想知道-retainCount到目前为止您在什么情况下使用,以及最终使用它可能发生的问题。

谢谢。

4

11 回答 11

247

你永远不应该使用-retainCount,因为它永远不会告诉你任何有用的东西。Foundation 和 AppKit/UIKit 框架的实现是不透明的;你不知道要保留什么,为什么要保留,谁在保留,什么时候保留等等。

例如:

  • 你会认为它[NSNumber numberWithInt:1]的 aretainCount为 1。它没有。是2。
  • 你会认为它@"Foo"的 aretainCount为 1。它没有。它是 1152921504606846975。
  • 你会认为它[NSString stringWithString:@"Foo"]的 aretainCount为 1。它没有。同样,它是 1152921504606846975。

基本上,因为任何东西都可以保留一个对象(并因此改变它retainCount),并且由于您没有运行应用程序的大多数代码的源代码,所以一个对象retainCount是没有意义的。

如果您试图找出一个对象没有被释放的原因,请使用 Instruments 中的 Leaks 工具。如果你想找出一个对象被过早释放的原因,请使用 Instruments 中的 Zombies 工具。

但不要使用-retainCount. 这是一个真正没有价值的方法。

编辑

请大家访问http://bugreport.apple.com并请求-retainCount弃用。要求的人越多越好。

编辑#2

作为更新,[NSNumber numberWithInt:1]现在有一个retainCount9223372036854775807。如果您的代码期望它是 2,那么您的代码现在已经损坏。

于 2011-01-08T22:20:04.190 回答
51

绝不!

严重地。只是不要这样做。

只需遵循内存管理指南,只发布你的内容allocnewcopy(或你最初调用retain的任何内容)。

@bbum在 SO 上说得最好,在他的博客上更详细。

于 2011-01-08T21:09:31.017 回答
14

自动释放的对象是检查 -retainCount 没有提供信息并且可能具有误导性的一种情况。保留计数不会告诉您在一个对象上调用了多少次 -autorelease 以及因此当当前自动释放池耗尽时它将被释放多少次。

于 2011-01-08T21:25:22.817 回答
9

当使用“仪器”进行检查时,我确实发现 retainCounts 非常有用。

使用“分配”工具,确保“记录引用计数”已打开,您可以进入任何对象并查看其 retainCount 历史记录。

通过将 allocs 和 release 配对,您可以很好地了解正在发生的事情,并且通常可以解决那些没有发布某些东西的困难情况。

这从未让我失望——包括在 iOS 的早期 beta 版本中发现错误。

于 2011-05-10T04:03:54.917 回答
5

查看有关 NSObject 的 Apple 文档,它几乎涵盖了您的问题: NSObject retainCount

简而言之,retainCount 可能对您毫无用处,除非您已经实现了自己的引用计数系统(我几乎可以保证您不会拥有)。

用苹果自己的话来说,retainCount“在调试内存管理问题时通常没有价值”。

于 2011-01-08T21:11:03.227 回答
4

当然,你永远不应该在你的代码中使用 retainCount 方法,因为它的值的含义取决于有多少自动释放被应用到对象上,这是你无法预测的。然而,它对于调试非常有用——尤其是当您在主事件循环之外调用 Appkit 对象方法的代码中寻找内存泄漏时——并且不应弃用它。

在你努力表达你的观点时,你严重夸大了价值的神秘本质。确实,它并不总是引用计数。有一些用于标志的特殊值,例如指示一个对象永远不应该被释放。像 1152921504606846975 这样的数字看起来非常神秘,直到你用十六进制写它并得到 0xfffffffffffffff。并且 9223372036854775807 是 0x7ffffffffffffff 十六进制。假设您每秒将 retainCount 增加 100,000,000 次,那么有人会选择使用这样的值作为标志,这并不奇怪,因为要获得与较大数字一样高的 retainCount 需要将近 3000 年的时间。

于 2015-11-28T22:03:42.900 回答
3

使用它会遇到什么问题?它所做的只是返回对象的保留计数。我从来没有打电话给它,也想不出任何理由。我已经在单例中覆盖了它,以确保它们没有被释放。

于 2011-01-08T21:09:44.760 回答
3

在您的应用程序启动并运行并做一些有用的事情之前,您不应该担心内存泄漏。

完成后,启动 Instruments 并使用该应用程序,看看是否真的发生了内存泄漏。在大多数情况下,您自己创建了一个对象(因此您拥有它)并在完成后忘记释放它。

不要在编写代码时尝试优化代码,当您实际正常使用应用程序时,您对可能泄漏内存或花费太长时间的猜测通常是错误的。

请尝试编写正确的代码,例如,如果您使用 alloc 等创建对象,请确保正确释放它。

于 2011-01-08T21:20:08.530 回答
0

切勿在代码中使用 -retainCount。但是,如果您使用,您将永远不会看到它返回零。想想为什么。:-)

于 2013-05-04T08:33:00.380 回答
-1

你永远不应该在你的代码中使用它,但它在调试时肯定会有所帮助

于 2013-03-07T14:51:13.073 回答
-1

Dave 的帖子中使用的示例是 NSNumber 和 NSStrings...所以,如果您使用其他一些类,例如 UIViews,我相信您会得到正确的答案(保留计数取决于实现,并且是可预测的)。

于 2018-06-04T18:38:20.987 回答