【问题标题】:A Simple Objective C xcode Memory Management Question一个简单的 Objective C xcode 内存管理问题
【发布时间】:2010-08-25 05:11:57
【问题描述】:

在下面的代码中,当 tapsMessage 被释放时, tapsLable.text 会被释放,还是赋值运算符以某种方式增加保留计数,以便 tapsLabel.text 继续可用?

NSString *tapsMessage = [[NSString alloc] initWithFormat:@"%d taps detected", numTaps];
tapsLabel.text = tapsMessage; // tapsLabel is a UILabel object
[tapsMessage release];

【问题讨论】:

    标签: iphone objective-c release


    【解决方案1】:

    这里有一个提示

    您可以为该对象编写retainCounter,然后您会看到它在分配之前和之后是什么。

    例如NSLog( @"%d", [tapsMessage retainCount] );

    这样你以后就可以通过写出retainCount来回答这些问题,因为它总是取决于属性的声明方式。

    【讨论】:

    • retainCount 应该很少被明确地查看。事实上,文档说不要使用retainCount 方法来检查内存管理问题。见here
    • @dreamlax 我知道它不是用于调试的,但是它确实让我们深入了解了引用计数的工作原理,这就是 OP 面临的问题。
    • 感谢 retainCount 日志记录提示。我相信我将来会使用它。我认为我最初的困惑是因为我没有意识到赋值运算符“=”会导致调用访问器方法。再次感谢您的帮助!
    【解决方案2】:

    tabsLabel.text 是 tapsLabel 的一个属性。我认为这是一个字符串属性,它在分配时执行 [目标副本]。没关系细节,是的,赋值运算符要么增加保留计数,要么复制值,所以你可以释放 tapsMessage,它仍然在 tapsLabel.text 中可用。

    Read more about properties here.

    编辑:在标题中查找 UILabel,是的,它为 text 属性做了一个副本。

    @property(nonatomic,copy)   NSString       *text;            // default is nil
    

    编辑:扩展评论中的重要问题

    如果您必须查看分配对象的每个对象的实现细节,怎么会有人知道什么时候发布什么时候不发布?

    您只需遵循内存管理规则。 refcounted 环境的关键在于,就内存管理而言,对象之间存在一些“松散耦合”。只要您正确地保留和释放,只要所有相关方的保留/释放匹配,其他人是否也保留和释放这些相同的对象就不是您关心的问题。

    【讨论】:

    • 我是objective-c的新手,但我知道C。如果赋值运算符有时会导致保留计数的复制或增加,有时不会,那将进行内存管理非常有问题。如果您必须查看分配给某些对象的每个对象的实现细节,怎么会有人知道何时发布以及何时不发布? (只是好奇)
    • 规则其实很简单,只要你习惯了。请参见此处:developer.apple.com/mac/library/documentation/cocoa/conceptual/… 在您的示例中, tapsMessage 的 retainCount 实际上不应增加,因为它是复制操作,而不是保留操作。正如您在内存管理指南中看到的那样,您无需查看实现细节即可知道何时(不)发布。
    • 感谢大家的帮助和患者。我想现在一切都清楚了。
    • 您还应该将最佳答案标记为 Stackoverflow 礼仪的一部分,无论您选择哪个,都已被接受。
    【解决方案3】:

    在第一行,你已经分配并初始化了一个 NSString。根据memory management rules,您拥有此对象,这意味着您有责任释放它。

    在第二行中,您将tapsMessage 字符串分配给text 属性。这个属性(假设tapsLabelUILabel)是用copy 属性声明的。对于不可变字符串(NSStrings),请求副本只会增加保留计数,因为不需要对数据进行实际复制(数据永远不会改变)。由于UILabel 复制了该字符串,因此它也声明了所有权(对象可以拥有多个所有者)。

    在第三行中,您放弃了所有权,但字符串仍然有一个所有者(标签),因此不会释放对象。

    【讨论】:

    • “对于不可变字符串 (NSStrings),请求副本只会增加保留计数,因为不需要对数据进行实际复制(数据永远不会改变)。” ——伟大的洞察力。这是否正式记录在任何地方,这就是它的工作原理?
    • 感谢您的大力帮助和解释。我想我现在一切都清楚了。
    【解决方案4】:

    它不会被释放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-11
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多