一个简单的 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
属性。这个属性(假设tapsLabel
是UILabel
)是用copy
属性声明的。对于不可变字符串(NSStrings),请求副本只会增加保留计数,因为不需要对数据进行实际复制(数据永远不会改变)。由于UILabel
复制了该字符串,因此它也声明了所有权(对象可以拥有多个所有者)。
在第三行中,您放弃了所有权,但字符串仍然有一个所有者(标签),因此不会释放对象。
【讨论】:
“对于不可变字符串 (NSStrings),请求副本只会增加保留计数,因为不需要对数据进行实际复制(数据永远不会改变)。” ——伟大的洞察力。这是否正式记录在任何地方,这就是它的工作原理? 感谢您的大力帮助和解释。我想我现在一切都清楚了。【参考方案4】:它不会被释放。
【讨论】:
以上是关于一个简单的 Objective C xcode 内存管理问题的主要内容,如果未能解决你的问题,请参考以下文章
如何用XCode创建Objective-c和C++的混编工程?
升级到 Xcode 10 后,无法快速识别 Objective C 类