【问题标题】:retainCount shows MaxIntretainCount 显示 MaxInt
【发布时间】:2011-09-08 15:06:00
【问题描述】:

在尝试打印对象的 retainCount 后,我​​得到 2147483647。为什么会得到这样的结果?应该是 1,不是吗?

NSString *myStr = [NSString new];
NSUInteger retCount = [myStr retainCount];
NSLog(@"refCount = %u", retCount);

2011-09-08 17:59:18.759 测试[51972:207] refCount = 2147483647

我使用 XCode 4.1 版。尝试编译器 GCC 4.2 和 LLVM GCC 4.2 - 结果相同。 垃圾收集选项设置为不受支持。

【问题讨论】:

  • 如果打印会发生什么:NSLog(@"refCount = %d", retCount);
  • NSLog(@"refCount = %d", retCount);打印相同的结果...
  • When to use -retainCount?的可能重复
  • @AppleVijay,DarkDust - 我刚刚阅读了常见问题解答,现在一切正常!感谢您的建议。
  • 永远不要打电话给retainCount,这没用。

标签: iphone objective-c ios xcode4


【解决方案1】:

NSString 在内存管理方面有些特殊。字符串文字(类似于@"foo")实际上是单例,每个具有相同内容的字符串都是同一个对象,因为它无论如何都不能被修改。由于[NSString new] 总是会创建一个无法修改的空字符串,因此您将始终得到无法释放的相同实例(因此高retainCount)。

试试这个 sn-p:

NSString *string1 = [NSString new];
NSString *string2 = [NSString new];
NSLog(@"Memory address of string1: %p", string1);
NSLog(@"Memory address of string2: %p", string2);

您会看到两个字符串具有相同的内存地址,因此是同一个对象。

【讨论】:

  • 另外:这可能是在享元设计模式中的原因,并且:“对于永远不会被释放的对象(也就是说,它们的释放方法什么都不做),这个方法应该返回 UINT_MAX”(引自NSObject-Class-Reference)
【解决方案2】:

这并不能直接回答您的问题,但 retainCount 并不是真的很有用,不应该用于测试。有关详细信息,请参阅此 SO 帖子。 When to use -retainCount?

【讨论】:

  • +1,除了好奇之外,没有理由永远查看retainCount。如果你评估 retainCount 你做错了什么。
  • 检查对象的保留计数的唯一效果是,您最终会回到这里发布令人困惑的问题,即为什么该数字在没有您的情况下会四处移动。答案是:这个数字在没有你的情况下四处移动。所以不要用它来调试你的保留/释放代码。
【解决方案3】:

虽然 NSString 是一种奇怪的情况(框架中还有其他情况),但您也可能在其他情况下遇到这种情况 - 这是创建单例对象的方法之一。

单例在应用程序中只存在一次,它永远不会被释放是非常重要的!因此,它会覆盖 NSObject 的一些方法,包括(但不限于):

- (id)release {
    // Ignore the release!
    return self;
}

- (NSUInteger)retainCount {
    // We are never going to be released
    return UINT_MAX;
}

这个对象永远不会被释放,并通过具有高得离谱的保留计数告诉框架它是一个单例。

查看this link 了解有关单例对象的更多信息。

【讨论】:

  • 它告诉框架没有这样的事情; retainCount 的返回值从不被框架使用(除了一些限制在非常特殊的使用范围内的特殊情况)。在单例的上下文中覆盖 retainCount 的建议本身就是浪费时间。
  • 对不起,我的意思不是这么明确——这只是一个措辞非常糟糕的句子!我的意思类似于cocoadev.com/index.pl?SingletonDesignPattern - 即'表示无法释放的对象':)
【解决方案4】:

我已经多次看到关于 NSStrings 的这种情况,当您尝试以这种方式查看字符串的 retainCounts 时,retainCount 返回最大计数而不是实际计数。

试试这个;

NSString *myStr = [[NSString alloc] init];
NSUInteger retCount = [myStr retainCount];
NSLog(@"refCount = %u", retCount);

编辑:恢复的 NSUInteger

【讨论】:

  • retainCount 返回 NSUInteger。尽管该方法没用,但您至少应该使用正确的返回类型。无符号和有符号整数不能透明地互换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 2011-07-06
相关资源
最近更新 更多