【问题标题】:NSString length and retainCount. Clarification neededNSString 长度和retainCount。需要澄清
【发布时间】:2011-07-18 00:25:16
【问题描述】:

根据以下代码,请指教

NSString *str= [[NSString alloc] initWithString:@"Hello world"];   

NSLog(@"Length: %lu\n", [str length]);              // 11
NSLog(@"Retain count is %lu\n", [str retainCount]); //1152921504606846975

[str release];

NSLog(@"%lu\n", [str length]);                      // 11
NSLog(@"Retain count is %lu\n", [str retainCount]); //1152921504606846975
  1. 最初我想知道为什么这个数字这么大,但后来看到了post explaining it。让我问这个......为什么无论我使用%d还是%lu,这个数字都会发生很大变化。最初,我使用%d,但收到警告说“转换指定类型 int 但参数的类型为 NSUInteger(又名无符号长)。修复方法是将 %d 更改为 %lu” em>

  2. 为什么保留计数不减少?在发送str release 后,大数字仍然显示不变

  3. 为什么在发送release 后,我仍然可以访问str

【问题讨论】:

    标签: objective-c memory-management


    【解决方案1】:

    这可能是一个难以接受的答案,但这是你应该做的:

    1. 别担心。(就 %d/%lu 而言,那些说明符只是期望不同的数据类型,而 %d (int) 与 %lu(无符号长))
    2. 别担心。
    3. 不要这样做,尤其不要依赖它。

    这可能是因为您从一个常量字符串 (@"Hello world") 开始,当您调用 release 时内存没有被释放,并且 retainCount 很大。但是如果你必须关心retainCount,那你就错了。

    您在正确的位置释放字符串,这很重要——以后不要尝试使用它。

    【讨论】:

    • 我在objective-c中读到的所有关于retain的内容都让我得出了同样的结论。别担心。
    • 很快我们就会有 ARC,然后我们会看到下一个难度级别是什么。
    • 下一个难度级别将是精神上掌握对象图 :)
    • @jtbandes - 在这种情况下,会有很多问题询问如何修复 Xcode 和 LLVM 会抛出的所有编译器错误。
    • @Abizern:是的,比如“为什么我不能打电话给-release??!1!”
    【解决方案2】:

    最终,行为是由 NSString 的实现定义的——只要在每种情况下正确使用保留/释放,你就会安全。

    可能发生的事情:NSString 字面量是不朽的。你可以写while (1) { [@"String" release]; },不会有问题。

    您调用的复制 ctor 可能会返回指向字符串文字的指针。在伪代码中:

    - (id)initWithString:(NSString *)str
    {
        self = [super init];
        if (self != nil) {
            if ([str _isStringLiteral] || [str _isImmutable]) {
                [self release];
                return [str retain];
            }
            ...
    }
    

    在这种情况下,当通过[[NSString alloc] initWithString:stringLiteral] 传递时,您将返回指向字符串文字的指针。由于将release 发送到不朽的字符串文字没有任何作用,您可以看到为什么它仍然是一个有效的对象,而您可以假定它是一个已释放的对象。

    永远不要依赖这些细节/优化,只需使用正常的生命周期和引用计数就可以了。

    【讨论】:

      猜你喜欢
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      • 2012-07-18
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多