释放、Dealloc 和 Self 引用

发布于 2024-07-29 16:12:15 字数 623 浏览 4 评论 0原文

所以我想我已经解决了所有这些问题。 然后突然我得到一个我无法弄清楚的错误(崩溃)。 然后,在进行了修复事故的研究后,我发现我认为我所了解的有关这些关键领域的一切都有些错误。

下面是我要提出的 8 个问题,希望有人能回答——这些问题的答案将极大地帮助我让我的理解回到正轨。 提前致谢!

Q1) 如果该引用为零,可以在对象上调用 Release 吗? 这应该是无害的,对吧?

Q2) 如果该引用已被释放且引用计数为 0,是否可以在对象上调用 Release?

Q3) 释放后是否需要设置对 nil 的引用? 如果不将其设置为零会发生什么?

Q4)nil 和 NULL 之间真的有区别吗?或者它只是一种语义,可以帮助读者/开发人员只需看一眼就知道对象类型?

Q5) 使用属性需要使用“Self”指针吗?

Q6) 使用实例变量要求不使用“Self”指针?

Q7) 我什么时候想使用实例变量而不是它的属性? 我认为值类型数据成员没问题,因为它们不涉及释放和保留。

Q8) 是否有必要在 dealloc 函数中调用对象的 dealloc? 在许多示例中,我看到 Release 被调用,但没有 Dealloc - 这样的教程不正确吗?

So I thought I had all these questions all figured out. Then all of a sudden I get an error (a crash) I can't figure out. Then after doing research to remedy the crash, I notice everything that I thought I knew about these critical areas are somewhat wrong.

Below are 8 questions I am just going to shoot out there in hopes of somebody answering - the answers to these will greatly help me get my understanding back on track. Thanks ahead of time!

Q1) Is it okay to call Release on an object if that reference is nil? This should be harmless, right?

Q2) Is it okay to call Release on an object if that reference has been released and as a reference count of 0?

Q3) Is it necessary to set a reference to nil AFTER releasing it? What happens if you dont set it to nil?

Q4) Is there really a difference between nil and NULL, or is it just a semantic thing to help the reader/developer know the object type just by glancing at it?

Q5) Using properties REQUIRE the use of the 'Self' pointer?

Q6) Using instance variables requires that the 'Self' pointer is NOT used?

Q7) When would I ever want to use an instance variable instead of its property? I'd imagine value type data members are okay since their is not releasing and retaining involved.

Q8) Is it necessary to call an object's dealloc from within the dealloc function?
In many examples I have seen Release being called, but not Dealloc - are such tutorials incorrect?

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

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

发布评论

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

评论(5

筑梦 2024-08-05 16:12:15

A1) [nil release] 很好(不会做任何事情)

A2) 不。在对象被释放后不要触摸它们。 释放后应将它们设置为零。

A3) 没有必要将已释放的指针设置为 nil,但您会得到悬空指针(即,您无法判断对象是否有效)。 将属性设置为 nil 通常用于释放底层 ivar,因此不这样做可能会导致内存泄漏

A4) nil 和 NULL 都是零,因此在技术上是相同的。

A5) 是的,您必须使用 self.someProperty 作为属性,就像您可以使用 [self someProperty] 如果它只是一个方法

A6) self 本质上是一个结构体,这样你就可以像这样访问ivars:self->someIvar。 不过,没有必要这样做。

A7) 当您出于某种原因不想运行 setter/getter 方法时。 当 setter 不允许 nil 值时,我偶尔会使用它,并且我需要释放变量

A8) 当释放被调用正确的次数时,会自动调用 dealloc。 你不应该直接调用 dealloc([super dealloc] 除外)

A1) [nil release] is fine (won't do anything)

A2) No. Don't touch objects after they've been deallocated. They should be set to nil after they are released.

A3) It's not necessary to set a released pointer to nil, but you get dangling pointers (i.e., you can't tell if an object is valid or not). Setting a property to nil is often used to release the underlying ivar, so failing to do this can cause a memory leak

A4) nil and NULL are both zero, so are technically the same.

A5) Yes, you must use self.someProperty for properties, just as you would use [self someProperty] if it was just a method

A6) self is essentially a struct, so you can access ivars like so: self->someIvar. There is no need to, though.

A7) When you don't want to run the setter/getter methods for whatever reason. I use it ocassionally when the setter doesn't allow nil values, and I need to release the variable

A8) dealloc is called automatically when release is called the correct amount of times. You should never call dealloc directly (except for [super dealloc])

守不住的情 2024-08-05 16:12:15

你可能应该把这个问题分成多个不同的问题,但我会咬牙切齿。

  1. 是的,任何发送到 nil 的消息都是空操作。
  2. 不会。引用计数为 0 的对象已经或即将被销毁,发送给它的任何消息都将导致崩溃,或者充其量是异常。
  3. 这取决于实际情况。 如果您在 -dealloc 中释放内容,那么可能不会。 如果它是一个仅限于特定方法的对象,那么可能不会。 如果是重复使用的ivar,我会说是的。 在前两种情况下,如果您不将指针设置为 nil,则不会发生任何事情,因为您通常无法再访问这些指针。 但在最后一种情况下,您仍然可以访问指向已释放内存的指针。 如果您向其发送消息或尝试取消引用它,您的应用程序将会崩溃。
  4. 它们都等于 0。按照约定,nil 用于对象指针,NULL 用于任何其他指针,但混合它们不会导致任何问题。
  5. 如果您想调用属性 getter/setter,那么可以。 如果你想直接访问它封装的ivar(不常见),不行。
  6. 不,您可以使用语法 self->ivar 访问实例变量。 事实上,当您仅输入 ivar 时,编译器会隐式添加 self-> 取消引用。
  7. 不确定你在这里的意思。
  8. 您应该调用 -dealloc 的唯一时间是在您自己的 -dealloc 方法中调用 [super dealloc]; 时。 对于任何其他对象,您应该始终只调用 -release

You should probably have split this question up into multiple different questions, but I'll bite.

  1. Yes, any message sent to nil is a no-op.
  2. No. An object with a ref-count of 0 has been, or imminently will be destroyed and any messages sent to it will cause a crash, or at best, an exception.
  3. It depends on the situation. If you're releasing things in -dealloc, then probably not. If it's an object that is scoped to a particular method, then probably not. If it's an ivar that is reused, I'd say yes. In the first two cases, nothing will happen if you don't set the pointers to nil, since you usually won't be able to access those pointers anymore. In the last case though, you still can access the pointer, which is pointing to deallocated memory. If you send it a message or try to dereference it, your app will crash.
  4. They are both equal to 0. By convention nil is used for object pointers, and NULL is used for any other pointers, but mixing them won't cause any problems.
  5. If you want to invoke the property getter/setter, then yes. If you want to access the ivar it encapsulates directly (uncommon), no.
  6. No, you can access instance variables using the syntax self->ivar. In fact, when you type just ivar, the compiler implicitly adds the self-> dereferencing.
  7. Not sure what you mean here.
  8. The only time you should be calling -dealloc is when calling [super dealloc]; in your own -dealloc methods. For any other objects you should always just call -release.
很酷不放纵 2024-08-05 16:12:15

其他人已经充分回答了1-6。

(7) Apple 建议您在 init 和 dealloc 中直接使用实例变量。 这主要是因为对象(特别是如果它是子类化的)在这两个方法中仅部分设置,因此如果调用 setter/getter 具有除琐碎操作以外的任何内容,则调用 setter/getter 可能会导致不正确的行为。 一般来说,您可以安全地直接(而不是通过 getter)访问对象中的 ivar,并且这样做会稍微更有效(仅与 iPhone 相关)。 一般来说,您应该在所有情况下使用 setter,特别是当您的对象可能被子类化或者其他人可能正在观察该属性时。

(8) 你永远不会调用 dealloc(dealloc 方法中的 [super dealloc] 除外)。 如果您拥有另一个对象的所有权,那么您应该放弃该所有权(通过调用release或autorelease)。 如果合适的话,系统将在对象上调用 dealloc。 但你永远不会自己调用dealloc。 阅读内存管理规则(只有 9 段,理解这一点至关重要)。

Others have answered 1-6 adequately.

(7) Apple recommends you use the instance variable directly in both your init and dealloc. Primarily this is because the object (especially if it is subclassed) is only partially set up during both of these methods, and so calling setters/getters may result in incorrect behavior if they have anything other than trivial actions. Generally you can safely access the ivar directly (rather than via the getter) in your object, and it will be marginally more effecient to do so (only relevent on the iPhone). Generally you should use the setter in all cases, especially if your object may be subclassed or if others may be observing the property.

(8) You never, ever, call dealloc (except [super dealloc] from within the dealloc method). If you have an ownership on another object, then you should relinquish that ownership (by calling release or autorelease). The system will then call dealloc on the object if appropriate. But you never call dealloc yourself. Read the memory management rules (its only 9 paragraphs and is vital to understand).

凡间太子 2024-08-05 16:12:15

好的。 我已经确认不将 B 设置为零就可以了。
所以,现在,我在创建 B 控制器时(当我想导航到它时)不检查 nil 。

相反,我释放 B,然后创建控制器并将其分配给 B。
然后,在 A 的 viewDidAppear 方法中,我释放了 B。

我相信该线程现在已关闭。 谢谢!

Ok. I have confirmed that not setting B to nil did the trick.
So, now, i dont check for nil when creating the B controller (when i want to navigate to it).

Instead, i release B, then i create the controller and assign it to B.
Then, in A's viewDidAppear method, i release B.

I believe this thread is now closed. Thanks!

不气馁 2024-08-05 16:12:15

A4) 它们的类型不同。 它们都是零,但 NULL 是一个 void *,nil 是一个 id,Nil 是一个类指针。

A4) They differ in their types. They're all zero, but NULL is a void *, nil is an id, and Nil is a Class pointer.

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