【问题标题】:How Objective-C handles the memory of immutable strings [duplicate]Objective-C 如何处理不可变字符串的内存 [重复]
【发布时间】:2012-06-30 06:22:02
【问题描述】:

在我的研究中,我遇到了一些奇怪的事情。

@interface Class {
    NSString *_string
}

- (void) Method1 {
    _string = @"ASDF";
}

最初我认为_string 是自动释放池的一部分,并且真的没有考虑它的内存方面。

阅读此 SO 帖子后Objective C NSString* property retain count oddity 我意识到不,不是这样,_string 的保留计数实际上是 UINT_MAX

显然,我认为_string 是自动释放池的一部分是侥幸,而我处理变量的方式只是以某种方式解决了。不过,我想知道的是:@"ASDF" 什么时候被扔掉?我知道我应该使用属性和设置器,但可能有很多代码看起来像这样,因为将常量分配给变量非常直观。

这些不可变的字面值NSStrings 的生命周期是什么?[_string length] 何时真正返回错误,因为@"ASDF" 不再驻留在内存中?

【问题讨论】:

  • 您似乎也对自动释放池的工作方式感到困惑。如果该字符串是自动释放的,那么(假设 ARC 不在播放中)您将无法在那里正确管理您的内存。

标签: objective-c cocoa memory-management nsstring literals


【解决方案1】:

来自Is a literal NSString autoreleased or does it need to be released?

编译器分配的字符串(格式为@"STRING")是常量,并且 所以给他们的 -retain、-release 和 -autorelease 消息会被忽略。 在这种情况下,您不必释放或自动释放 foo (但它 不会受伤)。

当你这样做时,在引擎盖下

NSString* yourString = @"ABC";

字符串将存储在称为数据段的内存区域中。该区域在应用程序启动后永远不会改变。这里的字符串被视为您的应用程序的常量。同时字符串也是一个对象,所以如果你想保留它,你可以调用retaincopy

当你这样做时,反之

NSString* yourString = // alloc-init

你在堆上创建了一个对象。如果您忘记释放,则会发生内存泄漏。如果其他人破坏了它,而您尝试访问它,则您无法访问该内存位置。

希望对您有所帮助。

【讨论】:

  • @user1289479 你可以吗?
  • 是的,很容易理解你的解释,所以现在我知道这些常量是如何工作的了,谢谢
【解决方案2】:

手动创建的不可变字符串 (NSString) 遵循正常的引用计数规则和生命周期。

在您的示例中,字符串更加特殊,因为它实际上是字符串文字。与任何文字一样,它们驻留在特殊内存中,并且仅在可执行文件终止时被销毁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2014-06-14
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    相关资源
    最近更新 更多