我想在方法NSString
中打印AppDelegate
类中的保留计数didFinishLaunchingWithOptions
NSString *str = [[NSString alloc] init];
NSLog(@"str retain count %d",[str retainCount]);
但它总是给出-1而不是+1....为什么???
NSUIntegerMax
表示返回的对象是不朽的。这曾经在文档中,但后来被删除(因为-retainCount
非常不鼓励)。
在 MRC 中,有些人实际上会覆盖-retainCount
以防止他们的单例被释放。
在这种情况下,[[NSString alloc] init]
返回一个常量/不朽是一种逻辑优化,而不是为每个请求创建一个空字符串。当然,你不应该在你的程序中依赖这个细节/行为。
苹果文档说:
特别注意事项
这种方法在调试内存管理问题时没有任何价值。因为任何数量的框架对象可能已经保留了一个对象以保存对它的引用,而同时自动释放池可能在一个对象上保存任何数量的延迟释放,所以您不太可能从中获得有用的信息方法。
所以你不应该指望它的正确性。
此外,-1
实际上是最大的无符号整数,而不是负值。保留计数返回NSUInteger
,所以你应该使用%u
而不是%d
。
-retainCount
正如其他人的答案所指出的那样,通常您不应再使用该方法。原因是,很多保留/释放工作是在NSString
类内部完成的,具体取决于您如何创建它。当您创建一个时,NSString
您实际上可以创建许多NSString
子类之一(id
初始化程序的返回类型不是特定的)。
所有NSConstantStrings
(由 创建的@""
)都是不可释放的 - 它们在程序的持续时间内存在(由 gcc 和 clang 指定)。因此,Apple 任意将其设置retainCount
为可能的最高无符号整数(如果它被读取为有符号,则为 -1,就像这里一样),因为在程序执行期间保持活动的常量对象没有任何意义保留计数。
当您以您的方式创建一个空字符串时,Apple 很可能只是自动将您指向@""
内存中的常量,因为它在运行时占用的空间更少。由于您的对象现在是NSConstantString
,因此实现它以返回保留计数 -1。
编辑:顺便说一句,NSConstantString
它的子类NSString
必须实现实现的方法NSString
,包括-retainCount
. 这就是为什么您实际上可以-retainCount
在一个常量字符串对象上调用该方法(以及为什么 Apple 让它返回一个特殊值)。这种继承关系可以在表NSString.h
头底部附近找到。