【问题标题】:Should I retain NSString when it points to a literal?当它指向文字时,我应该保留 NSString 吗?
【发布时间】:2012-10-30 03:11:37
【问题描述】:
    if (url_leng)
    {
        NSString *open_string;

        if      (g_system_status.language_code == 0)
            open_string = @"Open";
        else if (g_system_status.language_code == 1)
            open_string = @"Abrir";
        [open_string retain];
        [alert addButtonWithTitle : open_string];
        g_scan_result = targ_url;               
    }

考虑上面的代码段。我的问题是关于“保留”声明。不知何故,我需要保留语句来使代码工作。我唯一的解释是当 open_string 超出范围时,将对它进行发布调用。因此需要一个保留调用来保存该值。

希望有人能证实这一点......

还想问在条件块之后是否需要字符串的释放语句?


更新:(在阅读了您的善意建议和宝贵见解后)

尝试了以下修改:

    if (url_leng)
    {            
        if      (g_system_status.language_code == 0)
            [alert addButtonWithTitle : @"Open"];
        else if (g_system_status.language_code == 1)
            [alert addButtonWithTitle : @"Abrir"];
        else
            [alert addButtonWithTitle : @"Open"];
        g_scan_result = targ_url;               
    }

现在似乎一切正常(即使没有保留语句)。

【问题讨论】:

  • 首先,如果 language_code 不是 0 或 1,您可能在 open_string 变量中有一个未初始化的值(取决于 LLVM 版本)。其次,您在这里处理的是字符串常量,can have interesting reference counting behavior.
  • 谢谢你的评论,你和rmaddy有同样的看法吗?那是根本不需要保留调用...
  • 另外,如果您想使您的应用程序国际化,您可能应该查看developer.apple.com/internationalization,因为 Apple 提供了很多有用的功能,例如NSLocalizedString
  • @Stanley 保留是不必要且不需要的。您所使用的所有open_string 只是作为传递给-addButtonWithTitle: 的东西(它将根据需要保留字符串本身)。此外,正如上面链接的问题所指出的,字符串常量是一种特殊情况,保留和释放不能像您想象的那样工作。事实上,如果您将-retain 用于其他任何事情,您将在该方法结束时泄漏内存,因为您没有与-release 平衡它。同样,您还需要在初始化 open_string 时将其设置为 nil,否则您可能会看到奇怪的行为。
  • 感谢您的宝贵见解,将按照建议再次完成整个事情。

标签: objective-c ios nsstring retaincount


【解决方案1】:

open_string 是一个指向字符串字面量的 NSString 指针。字符串文字存在于堆栈中。在您传递对字符串文字的引用的代码中,如果您想保留该数据,请将它们复制到堆上。如果你拥有一个对象(即,在一个对象上调用了 retain/copy/new/alloc),你有责任释放它,否则你会泄漏内存。

【讨论】:

  • 感谢您的回答,您认为retain语句有必要(或适当)吗?
  • 你在 addButtonWithTitle: 警报对象的方法中做什么?注释掉保留语句。在 addButtonWithTitle: 中调用 [open_string copy],然后在返回该方法之前释放它。按照 Brad Larson 评论中的链接了解字符串常量。
  • 感谢您的评论,我想我需要深入了解一下。
  • 警报对象是为响应 ZXing 扫描结果而设置的。不确定问题是否与导入的 ZXing 代码有关。但 QRScanner 似乎按预期工作,即使代码导入过程有点混乱。
  • 也感谢有关字符串文字的建议和信息。应该更多地了解这些字符串常量,因为它们经常被使用。
【解决方案2】:

此代码中绝对不需要retain。如果你有问题,它不在这里。将open_string 分配给警报后,您就不再需要它了。您必须在其他地方遇到内存管理问题。

也许问题在于language_code 不是 0 和 1。在这种情况下,您永远不会正确初始化 open_string。您至少应该分配 nil 或以某种方式处理这种情况。

考虑使用 ARC,让您的生活更轻松。

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 1970-01-01
    • 2019-04-03
    • 2013-09-29
    • 1970-01-01
    • 2014-06-12
    • 2012-03-08
    • 1970-01-01
    • 2011-05-26
    相关资源
    最近更新 更多