2012-02-01 59 views
1

这里是我的代码奇怪保留新创建的字符串对象的数量

#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 becase的是新创建的对象,但结果是1152921504606846. 这里有什么问题?

+0

请勿使用retainCount。请参阅 - [何时使用-retainCount?](http://stackoverflow.com/questions/4636146/when-to-use-retaincount) – beryllium 2012-02-01 11:59:51

+0

可能重复的[NSString保留计数](http://stackoverflow.com/questions/1390334/nsstring-retain-count) – 2012-02-01 15:05:13

回答

6

三个要点:

  1. 这有什么好做自动释放池。您的变量为alloc d,因此未添加到池中
  2. 从不使用retainCount进行调试。请参阅this question的回答
  3. 您的字符串实际上是一个常量,因此保留计数为可能是 MAX_INT。但是,你不应该依赖于
+0

我同意你的看法,但为什么大多数关于objective-c的书籍都使用retainCount方法来解释记忆管理? – Profo 2012-02-01 12:12:01

+2

我不知道。你必须问作者。 – 2012-02-01 12:13:30

+0

大声笑,感谢您的答案:) – Profo 2012-02-01 12:15:55

-2

只需更改%鲁%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; 
} 
+0

那么,什么结果显示你的代码?) – beryllium 2012-02-01 12:03:08

+3

1)'retainCount'返回一个'NSUInteger',所以'%lu'是正确的说明符。 2)你永远不应该评估'retainCount'。 3)因为在这种情况下,'NSString'将简单地自行优化并返回* constant *(unreleaseable)字符串'@“这是字符串对象”'而不是一个新对象,因此返回非常高的数字“retainCount” 。 – DarkDust 2012-02-01 12:24:00

1

看到什么铍上面说;)切勿使用-retainCount这就是说,这里有两个问题:

首先是不是在自动释放池,但在你的NSLog的。

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

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

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

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

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