理解何时在对象上调用retain方法?

6
什么时候应该使用retain?我理解它会增加对象引用计数,基本上下一个对该对象的release不会调用dealloc。好的,那又怎样呢?我看到一些说法认为这是一种约定俗成的做法,如果你关心一个对象,就将其retain。有没有相关的例子?这是真的吗?
编辑:我不是在寻找调试器告诉你要这样做还是那样做的情况。所以,我查阅了this
简而言之,以下是retain用法示例。
  • 在您的代码中,您调用了一个返回您不拥有的对象的方法
  • 您使用该对象
  • 然后您想要释放它 => 您无法这样做,因为您不是所有者
  • 您的解决方案是使用copyretain。如果您使用retain,则将获得该对象的所有权。
  • 然后,要释放该对象,您可以执行2个release(因为当您保留时引用计数为1 + 1)或直接在其上使用dealloc

就这样吗?我认为不是,因为一个对象可以有多个所有者。所以对于最后一点,调用dealloc将真正“杀死”该对象;但是通过2个release,您将不是所有者,但创建它的程序仍将是所有者,因此该对象仍然存在(泄漏?僵尸?)

请帮助我理清思路。


可能是Objective-C内存管理的重复问题。 - Abizern
我不认为需要对此进行踩票。已点赞。 - Bourne
我对保留(retain)很困惑。我不明白为什么要使用它。我试图在刚才的编辑中表达我如何使用它。 - Marcel Falliere
1
你的修改是不正确的:你永远不应该直接调用dealloc。而且你也不应该调用两次release。在一个方法或类中平衡retain和release的数量。 - Felix Lamouroux
4个回答

6
你可以在内存管理指南中找到所有答案。
编辑后,以下是更具体的细节:
在你的代码中,你调用了一个返回你不拥有的对象的方法。因为你不拥有它,所以你无法控制它的生命周期。当你仍然依赖它作为有效对象时,它可能被释放掉。
你使用该对象时,永远不能确定它是否存在。
然后你想释放它=>你不能这样做,因为你不是它的所有者。但是为什么你想要释放它呢?你不拥有这个对象,所以你不负责内存管理。
看起来你想调用release,因为你认为这是如何管理内存的,而retain则允许你调用它。
这是应该工作的方式:
1.你调用一个返回对象的方法。如果你没有通过调用allocnewcopymutableCopy接收到此对象,则根据内存管理指南,你不拥有该对象,因此你不负责管理该内存。
2.在大多数情况下,你可以假设你已经获得了一个自动释放的对象。这意味着你无法控制它的生命周期。为了确保它在你完成使用之前不被释放,你调用retain方法。现在你拥有了这个对象,并负责在未来某个时刻调用release方法。对于对象的保留计数感到困惑是初学者的错误。不要这样做。所有重要的事情都是你负责调用release
3.你使用该对象时要记住一般的内存管理范例。例如,如果你将此对象添加到NSArray中,则该数组将保留它。
4.一旦你完成了使用该对象的操作,就调用release方法。同样,不要关心对象的保留计数,或其他对象是否正在使用该对象。所有重要的事情都是你已经平衡了对retain的调用与对release的相等数量的调用。

1
非常棒的@Abizen。这就是我所需要的。 - Marcel Falliere

1

通常情况下,只有在需要时才会显式使用retain,并且当出现这种情况时,Xcode调试器会告诉我刚刚发生了什么。通常由于某些原因(开发人员的管理不善或后台正在进行某些发布),如果对已释放的对象执行任何操作,都会导致崩溃。只需阅读控制台上的日志,查看Xcode调试器进行调试,通常就可以确定哪个对象引起了问题。


0
Marcel,内存管理是开发iOS应用程序的关键点。建议你阅读其他人建议的苹果文档。
我可以在这里添加一些信息来帮助您满足需求。
使用Obj-C进行内存管理的过程是基于计数的。这意味着任何时候当你“保留”某个对象时,系统都会为该对象提高一个计数器。例如,如果您创建了一个按钮并“保留”它,它将具有值1。如果您再次保留它,它将具有值2。要完全销毁此对象,您需要释放两次。
任何时候,一个对象的值为0,它就会被销毁。
我的个人意见:如果您想对应用程序的内存管理有很好的控制,最好明确地保留和销毁您的对象,在可能的情况下避免自动释放。再次强调,这是我的个人意见。我喜欢了解我的应用程序内存过程,这就是为什么我更喜欢精确处理它的原因。
当然,这不是最好的方法,每个开发人员都会选择不同的方法来管理内存。
再次强调:花些时间阅读Abizem建议的文档。相信您会更好地理解它。

谢谢Trinca。似乎必须像CSS z-index一样使用retain...如果您想将元素保持在前面,因此要放置一个大的值。对于retain也是这样吗?您希望您的对象绝对存活(为什么?不知道!),因此您会保留它一两次...? - Marcel Falliere
2
@Marcel 不是这样的!绝对不是。当你想在当前范围之外保留一个对象时,你会保留它;而当你拥有一个对象时,你会释放它。你永远不会为了安全起见而多次保留。 - kubi
@Marcel - 内存管理是你需要注意的事情。你不需要多次保留一个对象,但你需要跟踪你的应用程序如何使用这个对象,因为在任何时候你都需要销毁它并且你必须知道如何做到这一点。或者,一旦它被销毁,你需要知道何时再次初始化它。记住,这是为了以安全的方式维护你的应用程序和系统运行。 - Trinca
@kubi 说得好。你认为一个好的现实世界的例子是什么?例如,你认为 UIViewController 在其 getter 方法中使用了 retain 吗?在我的应用程序中,如果我说 [[self view]release],它会做什么?retain 是否只适用于插件/框架开发者?我需要一个好的例子。 - Marcel Falliere

-1

我知道 retain 的作用。但我不知道什么时候使用它才是正确的。你提供的链接没有解释清楚。 - Marcel Falliere

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接