一个简单的 Objective C xcode 内存管理问题

Posted

技术标签:

【中文标题】一个简单的 Objective C xcode 内存管理问题【英文标题】:A Simple Objective C xcode Memory Management Question 【发布时间】: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];

【问题讨论】:

【参考方案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 实际上不应增加,因为它是复制操作,而不是保留操作。正如您在内存管理指南中看到的那样,您无需查看实现细节即可知道何时(不)发布。 感谢大家的帮助和患者。我想现在一切都清楚了。 您还应该将最佳答案标记为 *** 礼仪的一部分,无论您选择哪个,都已被接受。【参考方案3】:

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

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

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

【讨论】:

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

它不会被释放。

【讨论】:

以上是关于一个简单的 Objective C xcode 内存管理问题的主要内容,如果未能解决你的问题,请参考以下文章

如何用XCode创建Objective-c和C++的混编工程?

在Objective c程序(Xcode)中使用汇编代码

升级到 Xcode 10 后,无法快速识别 Objective C 类

开发iOS程序一定要用object-c吗?可以用C/C++么?

xcode Objective C-构建类/对象

如何在Objective C中设置Xcode 8中的约束