有人能告诉我在objective-c中保留和释放到底做了啥吗?

Posted

技术标签:

【中文标题】有人能告诉我在objective-c中保留和释放到底做了啥吗?【英文标题】:Can somebody tell me what retain and release exactly do in objective-c?有人能告诉我在objective-c中保留和释放到底做了什么吗? 【发布时间】:2011-11-08 23:40:58 【问题描述】:

我对保留和释放变量有点困惑。

这是我的问题:

    我分配了一个对象 AObject *A = [[Object alloc] init]

    这会增加保留计数吗?和拥有一样吗Object *A = [[[Object alloc] init] retain]. 我知道如果我们调用retain,对象将一直保留到我们释放它为止。

      2.1。 我有一个保留的Object A。这个Object A 作为参数传递给了一个函数。后来在功能中我发布了它。它会释放Object A 的内存吗?如果是,Object A 是否不再存在。

    2.2 继续使用 2.1,而不是发布 Object A。我创建了一个局部变量Object *B = A。如果我发布了Object B,它也会发布Object A。或者如果我保留B,它是否也会保留A

我有点困惑,所以我想请这里的任何人指导我走向正确的道路。

谢谢

【问题讨论】:

【参考方案1】:

Object *A = [[Object alloc] init] 这会增加保留计数吗?

是的,更具体地说,它可能会将保留计数初始化为 1。

是否与 Object *A = [[[Object alloc] init] retain] 相同。我知道如果我们调用retain,对象将一直保留到我们释放它为止。

不一样。这将增加两次保留计数。没有太多理由在同一个地方增加两次保留计数。如果你这样做了,你将负责调用 release 两次。

我有一个保留的对象 A。此对象 A 作为参数传递给函数。后来在功能中我发布了它。它会释放对象 A 的内存吗?如果是,对象A是否不再存在。

首先,您应该确保您了解释放是否释放内存取决于是否有其他所有者持有对该对象的引用。如果不止一个东西保留了对象,那么在这种情况下释放不会释放内存。

第二,坏主意。为了保持引用计数的完整性,您应该遵循某些模式。

    保留(或分配)实例变量,在 dealloc 或之前释放它们。 如果需要,保留(或分配)局部变量,并在退出方法之前释放它们。 调用者不拥有函数的返回值。这意味着您像处理局部变量一样处理函数返回值,但在返回它之前自动释放它而不是释放它。这样可以确保它至少持续足够长的时间,以便调用者在需要时保留它。

其中一种模式是方法调用者拥有对方法参数的引用,但是当函数返回时,调用者不拥有该引用。该方法不应释放调用者的引用。

继续 2.1,而不是释放对象 A。我创建了一个局部变量 Object *B = ObjectA。如果我释放了 B,它是否也会释放对象 A。或者如果我保留 B,它也会保留 A。

retain 和 release 被发送到对象,而不是引用。 A 和 B 引用同一个对象,因此在一个对象上调用 retain 或 release 与在另一个对象上调用相同。

[B retain] 和稍后以相同的方法 [B release] 是合法的,但可能没有必要。但不要只做[B release],从而剥夺A对该对象的所有权。

【讨论】:

如果我在一个函数中有一个局部变量,并且该函数被执行了,这个局部变量会被销毁还是只保留在内存中...... 变量会消失,但如果是指针,它指向的东西不会自动消失。【参考方案2】:

记住这一点:NARC。

New、Alloc、Retain、Cop​​y 是增加保留计数的 4 个命令。换句话说,对于每个 NARC,您都需要相应的释放来释放该内存。

【讨论】:

【参考方案3】:

调用alloc(或new)会增加保留计数。如果您在那之后再次retain,那将再次增加它。除了特定的通缉案件外,无需进行第二次保留。

主要规则是:alloc 的那个就是release 的那个。当然,如果你真的知道自己在做什么,你可以绕过它。

我有一个保留的对象 A。这个对象 A 被传递给一个函数 一个论点。后来在功能中我发布了它。会不会释放 对象 A 的内存?

基本上是的。

如果是,对象A是否不再存在。

再次是的,但有时,它仍然“在内存中”,因此调用它可能会在很短的时间内工作。很短。

继续使用 2.1,而不是释放对象 A。我创建了一个本地 变量对象 *B = 对象A。如果我释放 B 是否也会释放 对象A。或者如果我保留B,它是否也会保留A。

如果保留 B,则 A 引用的对象将保留两次。所以释放B不会释放A引用的对象。但是如果你不保留B,那么释放B等于释放A(只有一个保留计数)。

提示

想象一下,您声明的任何引用(Balloon* 绳索)都是您手中的绳索,用于保留包含事物的 Balloon 对象。绳子不是物体。对象(气球)是在内存中的某个地方(这里在空间中)创建的。如果你第二次保留,你会得到另一条绳子到那个气球上,然后把它拿到另一只手上。要释放气球,您需要释放两条绳索。

请注意,alloc(或 new)会创建一条绳索,因此您刚刚创建的气球不会立即进入外太空。

清楚吗?

【讨论】:

-init 不会增加保留计数。另一方面,+alloc 确实如此。 @Bavarious:谢谢你的更正,我已经写信了 :-)【参考方案4】:

1) init 不等于retain。

init 方法实际上将对象置于正确的“初始化”状态,以便可以通过调用父类的 init 方法来使用对象,以及设置放置在实现的 init 方法中的任何附加设置对象 .m 文件。保留实际上只是将保留计数增加 1。

2) 2.1) 当你为一个对象分配内存时,你想在相同的范围内释放它,所以当你将一个对象传递给一个方法时,你不会在那里释放它。但是,如果您确实在传入对象引用的函数/方法中释放了它,那么它将被释放。不过,您无法完全确定对象本身何时会不复存在。

2.2) 当您说Object *B = ObjectA 时,您实际上并不是在创建另一个对象,而是在创建一个新的引用或指向 ObjectA 的指针。如果你在引用 B 上调用 release/retain,因为它指向与 ObjectA 相同的对象,它与在 ObjectA 上调用 release/retain 是一样的。

【讨论】:

以上是关于有人能告诉我在objective-c中保留和释放到底做了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章

完成处理程序和块之间的区别:[iOS]

在objective-c中保留对象

委托和对象保留objective-c (iOS)

使用Objective-C中的单例保留循环

Objective-C:UIApplicationMain第四个参数

Objective-C 确定哪些对象保留另一个对象