有人能告诉我在 Objective-C 中保留和释放到底做了什么吗?
我对保留和释放变量有点困惑。
这是我的问题:
我分配了一个对象 A
对象 *A = [[对象分配] init]
这会增加保留计数吗?和拥有一样吗
对象*A = [[[对象分配]初始化]保留]
。
我知道如果我们调用retain,该对象将被保留,直到我们释放它。
2.1. 我有一个保留的对象 A
。这个对象 A
作为参数传递给函数。后来在函数中我释放了它。它会释放对象A
的内存吗?如果是,则对象 A
是否不再存在。2.2 继续 2.1,而不是释放
对象 A
。我创建了一个局部变量Object *B = A
。如果我释放了对象 B
,它也会释放对象 A
。或者,如果我保留B
,它也会保留A
。
我有点困惑,所以我想请这里的任何人指导我走上正确的道路。
谢谢
I have a bit of confusion about retain and release variable.
These are my question:
I have an object A allocated
Object *A = [[Object alloc] init]
Does this increase the retain count? Is it the same as having
Object *A = [[[Object alloc] init] retain]
.
I know if we call retain, the object will be held until we released it.
2.1.
I have a retainedObject A
. ThisObject A
was passed to a function as an argument. Later in the function I released it. Will it release the memory of theObject A
? if it is, does theObject A
no longer existed.2.2
Follow on with 2.1, instead of releasingObject A
. I created a local variableObject *B = A
. If I releasedObject B
will it also releaseObject A
. Or if I retainB
, will it retainA
as well.
I am a bit of confused so I want to ask anyone here to directing me to the right path.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,更具体地说,它可能会将保留计数初始化为 1。
不一样。这将使保留计数增加两倍。没有太多理由在同一位置将保留计数增加两次。如果你这样做了,你将负责调用release两次。
首先,您应该确保您了解release是否释放内存取决于是否有其他所有者持有对该对象的引用。如果不止一件事保留了该对象,则在这种情况下release将不会释放内存。
第二,坏主意。为了保持引用计数的理智,您应该遵循某些模式。
其中一种模式是方法调用者不拥有对方法参数的引用,但当函数返回时,调用者不拥有该引用。该方法不应释放调用者的引用。
keep 和release 发送给对象,而不是引用。 A 和 B 引用同一个对象,因此对其中一个对象调用保留或释放与对另一个对象调用保留或释放相同。
在同一方法中
[B保留]
和稍后的[Brelease]
是合法的,但可能没有必要。但不要仅执行[B release]
,从而剥夺 A 对该对象的所有权。Yes, more specifically, likely, it initializes the retain count to 1.
Not the same. That will increase the retain count twice. There's not much reason to increase the retain count twice in the same place. If you did do that, you'd be responsible for calling release twice.
First, you should make sure that you understand that whether release frees memory or not depends on if there are other owners that are holding a reference to the object. If more than one thing has retained the object, then release will not free the memory in that case.
Second, bad idea. To keep sanity with reference counting, you should follow certain patterns.
One of the patterns is not for a method caller to own a reference to a method argument, but when the function returns the caller does not own the reference. The method should not release the caller's reference.
retain and release are sent to objects, not references. A and B refer to the same object, so it's the same calling retain or release on one as on the other.
It is legitimate, but probably unnecessary, to
[B retain]
and later in the same method[B release]
. But do not do[B release]
only, thereby expropriating A's ownership of the object.请记住这一点:NARC。
New、Alloc、Retain、Copy 这 4 个命令会增加保留计数。换句话说,对于每个 NARC,都需要相应的释放来释放该内存。
Remember this: NARC.
New, Alloc, Retain, Copy are the 4 commands that will increase the retain count. In other words, for every NARC, you need a corresponding release to release that memory.
调用
alloc
(或new
)会增加保留计数。如果此后您再次retain
,则会再次增加。除了特定的需要的情况之外,没有必要进行第二次保留。主要规则是:
分配
就是释放
。当然,如果您真正知道自己在做什么,则可以绕过它。基本上,是的。
是的,但有时,它仍然“在内存中”,因此对它的调用可能会在非常非常短的时间内起作用。很短。
如果保留 B,则 A 引用的对象将被保留两次。所以释放B并不会释放A引用的对象。但是如果不保留B,那么释放B就等于释放A(只有一个保留计数)。
提示
想象一下,您声明的任何引用(Balloon* 绳索)都是您手中的一根绳子,用于保留包含事物的 Balloon 对象。绳子不是物体。该对象(气球)是在内存中的某个位置(此处是在空间中)创建的。如果您第二次保留,您将用另一根绳子连接该气球并将其放在另一只手上。要释放气球,您需要释放两条绳子。
请注意,alloc(或 new)会创建一根绳子,因此您刚刚创建的气球不会立即进入外太空。
清楚了吗?
Calling
alloc
(ornew
) increases the retain count. If youretain
again after that, that increases it once again. There is no need to do that second retain except for specific wanted cases.The main rule is : the one that
alloc
is the one thatrelease
. Of course you can bypass that if you reaaly know what you are doing.Basically, Yes.
Yes again, but sometimes, it remains "in memory" so calls to it may work for a very very short time. Very short.
if you retain B, then the object references by A is retained twice. so releasing B does not free the object referenced by A. But if you don't retain B, then releasing B equals to releasing A (only one retain count).
Tip
Imagine that any reference you declare (Balloon* rope) is a rope you get in your hand to retain a Balloon object that contain things. The rope is not the object. The object (the balloon) is created somewhere in memory (here in the space). If you retain a second time, you get another rope to that balloon and get it in the other hand. To free the balloon, you need to free both ropes.
Note that alloc (or new) creates a rope so the balloon you've just created does not go immediatly in outerspace.
Is that clear ?
1)init与retain不同。
init 方法实际上将对象置于正确的“初始化”状态,以便可以通过调用父类 init 方法来使用该对象,以及设置放置在对象 .m 中实现的 init 方法中的任何其他设置文件。保留实际上只是将保留计数增加 1。
2) 2.1) 当您为对象分配内存时,您希望在相同的范围内释放它,因此当您将对象传递给方法时,您不会释放它它在那里。但是,如果您确实在传入对象引用的函数/方法中释放了它,那么它将被释放。不过,您无法完全确定该对象本身何时将不复存在。
2.2) 当你说
Object *B = ObjectA
时,你实际上并没有创建另一个对象,而是创建一个指向ObjectA的新引用或指针。如果对引用 B 调用release/retain,由于它指向与ObjectA 相同的对象,因此与对ObjectA 调用release/retain 是一样的。1) init is not the same as retain.
The init method actually puts the object in a correct "initialization" state so that the object can be used by calling the parent classes init method, as well as setting up any additional setup that is placed in the init method implemented in the objects .m file. The retain actually just increments the retain count by 1.
2) 2.1) When you allocate memory for an object, you want to release it in the same scope per say, so when you pass in an object into a method you wouldn't release it there. However, if you did release it in the function/method where it was passed in since you are passing in an object reference, it will be released. You can't be entirely sure when the object itself will cease to exist though.
2.2) When you say
Object *B = ObjectA
you aren't actually creating another object, but are creating a new reference or pointer to ObjectA. If you call release/retain on the reference B, since it's pointing to the same object as ObjectA, it's the same thing as calling release/retain on ObjectA.