NSString保留计数-1

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

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

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

NSUIntegerMax表示返回的对象是不朽的。 这曾经是在文档中,但已被删除(因为-retainCount非常灰心)。

在MRC中,有些人实际上会覆盖-retainCount来防止单身人士被释放。

在这种情况下,这是[[NSString alloc] init]返回一个常量/不变的逻辑优化,而不是为每个请求创build一个空string。 当然,你不应该依赖你的程序中的这个细节/行为。

苹果文档说:

特别注意事项

这种方法在debugging内存pipe理问题上没有任何价值。 因为任何数量的框架对象可能保留了一个对象来保存对它的引用,同时autorelease池可能在对象上保存了任意数量的延迟发布,所以很难从这个对象获得有用的信息方法。

所以你不应该指望它的正确性。

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

一般来说,不应再使用-retainCount方法,正如其他人的答案所指出的那样。 原因是,很多保留/释放工作是在NSString类内完成的,具体取决于你如何创build它。 当你创build一个NSString你实际上可能正在创build一个NSString子类(这个id返回types不是特定的)。

所有NSConstantStrings (由@""创build的)不可释放 – 它们在程序期间存在(由gcc和clang指定)。 因此,苹果已经任意地将其retainCount设置为可能的最高无符号整数(或者-1,如果它被读为有符号的,就像这里一样),因为对于在程序持续期间持续存在的常量对象是没有意义的一个保留计数。

当你以你所拥有的方式创build一个空string时,Apple可能会自动将你指向内存中的常量@"" ,因为它在运行时占用更less的空间。 由于你的对象现在是一个NSConstantString ,它的实现是返回保留计数-1。

编辑:顺便说一句,因为NSConstantStringNSString的子类,它必须实现NSString实现的方法,包括-retainCount 。 这就是为什么你可以实际调用常量string对象上的-retainCount方法(以及为什么苹果使它返回一个特殊的值)。 这个inheritance关系可以在NSString.h头部的底部find。