NSString 的保留计数为 -1。

3

我想在AppDelegate类的didFinishLaunchingWithOptions方法中打印NSString的保留计数

NSString *str = [[NSString alloc] init];
NSLog(@"str retain count %d",[str retainCount]);

但它总是给出-1而不是+1....为什么?

你永远不会这样创建一个字符串。为什么要这样做呢? - AlexWien
使用retainCount的第一条规则是,永远不要相信它们。 - Krishnabhadra
http://www.whentouseretaincount.com - Bryan Chen
3个回答

4

NSUIntegerMax表示返回的对象是不会被释放的。这个信息曾经在文档中出现过,但现在已经被删除了(因为非常不鼓励使用-retainCount)。

在MRC中,有些人会重写-retainCount以防止他们的单例被释放。

在这种情况下,[[NSString alloc] init]可以逻辑上优化为返回一个常量或不会被释放的对象,而不是为每个请求创建一个空字符串。当然,在你的程序中不应该依赖于这个细节和行为。


请给我建议,我的回答哪里不正确。我没有任何理由被踩。 - Anoop Vaidya
@AnoopVaidya 我没有给你的答案投反对票。如果我要猜的话:前两句话不是很清楚,那可能就是你原本回答的全部(如果我没记错的话)。是啊 - 我真的不喜欢没有解释的反对票:\ - justin

3

Apple文档指出:

特别考虑

这种方法在调试内存管理问题上没有价值。因为任何数量的框架对象可能已经保留了一个对象以持有对它的引用,同时自动释放池可能正在保留对象上的任意数个延迟释放,所以你很难从这种方法中获得有用的信息。

因此,你不应该指望它的正确性。

另外,-1实际上是最大的无符号整数,而不是负值。保留计数返回NSUInteger,因此您应该使用%u而不是%d


1
通常情况下,你不应再使用 -retainCount 方法,正如其他答案所指出的那样。原因是,取决于你如何创建它,许多保留/释放工作都在 NSString 类内部完成。当你创建一个 NSString 时,实际上可能会创建许多 NSString 子类之一(初始化程序的 id 返回类型不是特定的)。
所有 NSConstantStrings(由 @"" 创建的字符串)都是不可释放的 - 它们存在于程序的整个持续时间内(由 gcc 和 clang 指定)。因此,苹果公司已经任意地将其 retainCount 设置为最高的无符号整数(如果读取为有符号整数,则为 -1),因为对于一个在程序持续时间内存在的常量对象来说,拥有 retain count 是没有意义的。
当你以你所拥有的方式创建一个空字符串时,苹果公司很可能只是自动将你指向内存中的常量 @"",因为它在运行时占用的空间较小。由于你的对象现在是一个 NSConstantString,它被实现为返回 -1 的保留计数。

编辑: 顺便提一下,由于NSConstantStringNSString的子类,因此它必须实现NSString实现的方法,包括-retainCount。这就是为什么您实际上可以在常量字符串对象上调用-retainCount方法(以及为什么Apple使其返回一个特殊值)。这种继承关系可以在NSString.h头文件的底部找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接