奇怪保留新创建的字符串对象的计数

时间:2012-02-01 11:57:41

标签: objective-c

这是我的代码

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *str = [[NSString alloc]initWithString:@"This is string object"];
    NSLog(@"%lu", [str retainCount]);
    [pool drain];


    return 0;
}

我预计输出为1,因为它是新创建的对象,但结果是1152921504606846。 这有什么不对?

3 个答案:

答案 0 :(得分:6)

三个要点:

  1. 这与自动释放池无关。您的变量为alloc d,因此未将其添加到池中
  2. 切勿使用retainCount进行调试。查看this question
  3. 的答案
  4. 您的字符串实际上是一个常量,因此保留计数可能是 MAX_INT。但你不应该依赖那个

答案 1 :(得分:1)

看看上面说的是什么铍;)永远不要使用-retainCount那就是说,这里有两个问题:

第一个不在自动释放池中,而是在NSLog中。

-[NSObject retainCount]返回一个NSUInteger,它是32位宽或64位宽,具体取决于系统架构。当函数采用可变数量的参数时,始终将NSInteger值转换为(long),将NSUInteger值转换为(unsigned long),这是最佳实践。因此:

NSLog(@"%l", (long)[str integerValue]

NSLog(@"%lu", (unsigned long)[str retainCount])

第二个是优化:@“这是字符串对象”实际上是一个NSString,但它是一个特殊的NSString,称为NSCFConstantString,其保留计数为NSIntegerMax(意味着它们不能被解除分配)。 / p>

我刚刚运行了原始示例,看起来像是通过-initWithString:初始化的NSString返回原始字符串。在这种情况下,这是常量字符串,因此它返回NSIntegerMax。

答案 2 :(得分:-2)

只需将%lu更改为%d

int main (int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *str = [[NSString alloc]initWithString:@"This is string object"];
    NSLog(@"%d", [str retainCount]);
    [pool drain];


    return 0;
}