您如何看待 Objective-C 中每次迭代都会迭代保留计数并调用释放的这段代码?

发布于 2024-12-21 08:08:59 字数 304 浏览 2 评论 0原文

我仍在尝试理解我在我正在开发的一个项目中发现的这段代码,在我询问之前,创建它的人已经离开了公司。

代码如下:

-(void)releaseMySelf{
    for (int i=myRetainCount; i>1; i--) {
        [self release];
    }
    [self autorelease];
}

据我所知,在Objective-C内存管理模型中,第一条规则是分配另一个对象的对象,也负责在将来释放它。这就是我不明白这段代码的含义的原因。有什么意义吗?

I'm still trying to understand this piece of code that I found in a project I'm working on where the guy that created it left the company before I could ask.

This is the code:

-(void)releaseMySelf{
    for (int i=myRetainCount; i>1; i--) {
        [self release];
    }
    [self autorelease];
}

As far as I know, in Objective-C memory management model, the first rule is that the object that allocates another object, is also responsible to release it in the future. That's the reason I don't understand the meaning of this code. Is there is any meaning?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滴情不沾 2024-12-28 08:08:59

作者正在尝试解决不了解内存管理的问题。他假设一个对象有一个保留计数,每次保留都会增加该计数,因此尝试通过调用该数量的释放来减少它。很可能他还没有实现“以后也负责发布”。你理解的一部分。

但是,请在此处查看许多答案,例如此处此处此处

阅读 Apple 的内存管理概念

第一个链接包含来自 苹果

retainCount 方法不考虑任何挂起的自动释放
消息发送到接收者。

重要提示:此方法通常在调试内存时没有任何价值
管理问题。因为任意数量的框架对象都可能有
保留一个对象以保存对其的引用,而在
同时自动释放池可能持有任意数量的延迟
在物体上释放,你不太可能有用
来自此方法的信息
。了解基本规则
你必须遵守的内存管理,请阅读《内存管理》
规则”。要诊断内存管理问题,请使用合适的工具:
LLVM/Clang Static 分析器通常可以找到内存管理
甚至在运行程序之前就出现问题。对象分配工具
在仪器应用程序中(请参阅仪器用户指南)可以跟踪
对象分配和销毁。 Shark(请参阅 Shark 用户指南)
配置文件内存分配(以及您的许多其他方面)
程序)。


The author is trying to work around not understand memory management. He assumes that an object has a retain count that is increased by each retain and so tries to decrease it by calling that number of releases. Probably he has not implemented the "is also responsible to release it in the future." part of your understanding.

However see many answers here e.g. here and here and here.

Read Apple's memory management concepts.

The first link includes a quote from Apple

The retainCount method does not account for any pending autorelease
messages sent to the receiver.

Important: This method is typically of no value in debugging memory
management issues
. Because any number of framework objects may have
retained an object in order to hold references to it, while at the
same time autorelease pools may be holding any number of deferred
releases on an object, it is very unlikely that you can get useful
information from this method
. To understand the fundamental rules of
memory management that you must abide by, read “Memory Management
Rules”. To diagnose memory management problems, use a suitable tool:
The LLVM/Clang Static analyzer can typically find memory management
problems even before you run your program. The Object Alloc instrument
in the Instruments application (see Instruments User Guide) can track
object allocation and destruction. Shark (see Shark User Guide) also
profiles memory allocations (amongst numerous other aspects of your
program).

尘世孤行 2024-12-28 08:08:59

由于所有答案似乎都将 myRetainCount 误读为 [self keepCount],所以让我提供一个可以编写此代码的原因:可能是此代码以某种方式生成线程或以其他方式让客户端向其注册,并且 myRetainCount 实际上是这些客户端的数量,与实际操作系统保留计数分开保存。然而,每个客户端也可能得到自己的 ObjC 风格的保留。

因此,在请求中止的情况下可能会调用此函数,并且可以立即处理所有客户端,然后执行所有释放。这不是一个好的设计,但如果代码就是这样工作的(并且您没有遗漏 int myRetainCount = [self keepCount] 或重写保留/释放),那么至少它不一定有错误。

然而,这很可能是一种糟糕的责任分配,或者是一种为了避免保留圈而没有真正改进任何东西的笨拙和陈腐的尝试。

Since all answers seem to misread myRetainCount as [self retainCount], let me offer a reason why this code could have been written: It could be that this code is somehow spawning threads or otherwise having clients register with it, and that myRetainCount is effectively the number of those clients, kept separately from the actual OS retain count. However, each of the clients might get its own ObjC-style retain as well.

So this function might be called in a case where a request is aborted, and could just dispose of all the clients at once, and afterwards perform all the releases. It's not a good design, but if that's how the code works, (and you didn't leave out an int myRetainCount = [self retainCount], or overrides of retain/release) at least it's not necessarily buggy.

It is, however, very likely a bad distribution of responsibilities or a kludgey and hackneyed attempt at avoiding retain circles without really improving anything.

娇纵 2024-12-28 08:08:59

这是强制释放内存的肮脏黑客:如果程序的其余部分编写正确,您永远不需要做这样的事情。通常,您的保留和释放是平衡的,因此您永远不需要查看保留计数。这段代码说的是“我不知道谁保留了我而忘记释放,我只是想让我的记忆被释放;我不在乎其他引用从现在开始就悬空了”。这不会用 ARC 进行编译(奇怪的是,切换到 ARC 可能只是修复作者试图解决的错误)。

This is a dirty hack to force a memory release: if the rest of your program is written correctly, you never need to do anything like this. Normally, your retains and releases are in balance, so you never need to look at the retain count. What this piece of code says is "I don't know who retained me and forgot to release, I just want my memory to get released; I don't care that the others references would be dangling from now on". This is not going to compile with ARC (oddly enough, switching to ARC may just fix the error the author was trying to work around).

乖乖兔^ω^ 2024-12-28 08:08:59

该代码的含义是强制对象立即释放,无论未来的后果如何。 (并且会产生后果!)

该代码存在致命缺陷,因为它没有考虑到其他人实际上“拥有”该对象的事实。换句话说,某些东西“分配”了该对象,并且任何其他东西都可能“保留”该对象(可能是像 NSArray 这样的数据结构,可能是自动释放池,可能是堆栈帧上的一些代码只执行“保留”操作) );所有这些东西都共享该对象的所有权。如果对象自杀(这就是releaseMySelf所做的),这些“所有者”突然指向错误的内存,这将导致意外的行为。

希望这样编写的代码会崩溃。也许原作者通过在其他地方泄漏内存来避免这些崩溃。

The meaning of the code is to force the object to deallocate right now, no matter what the future consequences may be. (And there will be consequences!)

The code is fatally flawed because it doesn't account for the fact that someone else actually "owns" that object. In other words, something "alloced" that object, and any number of other things may have "retained" that object (maybe a data structure like NSArray, maybe an autorelease pool, maybe some code on the stackframe that just does a "retain"); all those things share ownership in this object. If the object commits suicide (which is what releaseMySelf does), these "owners" suddenly point to bad memory, and this will lead to unexpected behavior.

Hopefully code written like this will just crash. Perhaps the original author avoided these crashes by leaking memory elsewhere.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文