我还在努力理解我找到的一个项目中的这段代码,创建它的人在我问之前已经离开了公司。
以下是代码:
-(void)releaseMySelf{
for (int i=myRetainCount; i>1; i--) {
[self release];
}
[self autorelease];
}
据我所知,在Objective-C的内存管理模型中,第一个规则是分配另一个对象的对象也负责在未来释放它。这就是我不理解这段代码意义的原因。有意义吗?
我还在努力理解我找到的一个项目中的这段代码,创建它的人在我问之前已经离开了公司。
以下是代码:
-(void)releaseMySelf{
for (int i=myRetainCount; i>1; i--) {
[self release];
}
[self autorelease];
}
作者试图绕过不理解内存管理的问题。他假设一个对象有一个保留计数,每个保留都会增加,因此尝试通过调用相应数量的释放来减少它。也许他没有实现你的理解中的“还要负责在未来释放它”的部分。
请阅读苹果公司的内存管理概念。
第一个链接包括一个引用苹果公司的话:
retainCount方法不考虑发送给接收器的任何挂起自动释放消息。
重要提示: 此方法通常对调试内存管理问题没有价值。因为任何数量的框架对象可能已经保留了一个对象以保持对它的引用,同时自动释放池可能正在保持对一个对象的任意数量的延迟释放,所以你很难从这个方法中获得有用的信息。要了解必须遵守的内存管理基本规则,请阅读“内存管理规则”。要诊断内存管理问题,请使用适当的工具:LLVM/Clang静态分析器通常可以在运行程序之前发现内存管理问题。Instruments应用程序中的Object Alloc仪器(请参阅Instruments用户指南)可以跟踪对象分配和销毁。Shark(请参阅Shark用户指南)还可以分析内存分配(以及您的程序的众多其他方面)。
由于所有答案似乎都误将 myRetainCount 解读为 [self retainCount],所以让我来解释一下为什么会有人编写这段代码:可能是因为这段代码在某种程度上会生成线程或以其他方式使客户端向其注册,而myRetainCount有效地是这些客户端的数量,从实际操作系统保留计数中分开,但每个客户端可能也会获得自己的 ObjC风格的 retain。
因此,在请求被中止的情况下可能会调用此函数,并且可以立即处理所有客户端,然后执行所有释放操作。 这不是一个好的设计,但是如果代码就是这样工作的(并且您没有漏掉 int myRetainCount = [self retainCount] 或 retain/release 的覆盖),那至少它并不一定是有缺陷的。
然而,这很可能是职责分配不当或笨拙的尝试,旨在避免保留循环,而实际上并没有真正改进任何东西。
这是一种强制释放内存的不良方法:如果你的程序其余部分编写正确,你永远不需要做任何类似的事情。通常情况下,你的保留和释放是平衡的,因此你永远不需要查看保留计数。这段代码的含义是:“我不知道谁保留了我却忘记释放,我只想释放我的内存;我不在乎其他引用从现在开始会变为悬空引用。”这不会与ARC编译(奇怪的是,转换到ARC可能会解决作者试图解决的错误)。
myRetainCount
做什么,这都不可以。 - Jonathan Sterling