gpt4 book ai didi

ios - 如果我们覆盖保留/释放方法,我们是否会失去对 ARC 的 objc_retain()/objc_release() 优化?

转载 作者:行者123 更新时间:2023-11-29 10:35:26 29 4
gpt4 key购买 nike

已编辑:有些人认为 AsyncDisplayKit 中的 ASDealloc2MainObject 并没有真正覆盖保留/释放。我修改了 ASDealloc2MainObject ( line 405-428 of _AS-objc-internal.h ) 背后的源代码,在覆盖的 release 方法中添加了一个 printf() 并在我的 iPhone 上进行了几次测试。日志按预期打印。我的测试代码(包括一个继承自 ASDealloc2MainObject 的新类)是在启用 ARC 的情况下编译的。


我曾经认为在 ARC 下无法覆盖 retain/release 方法。结果我错了。这种技术涉及在 MRC 下编译的基类及其在 ARC 下编译的子类。

一个很好的例子是 Facebook AsyncDisplayKit . Facebook AsyncDisplayKit 框架中的许多类都继承自名为 ASDealloc2MainObject 的基类。 ASDealloc2MainObject 是一个在 MRC 下编译并覆盖 NSObject 的 retain/release 方法的类。同时ASDealloc2MainObject的子类在ARC下编译运行。

我有两个问题:

  1. > Quite a few blog posts在互联网上说,当 ARC 在编译期间插入内存管理代码时,它会插入低级 C 函数,例如 objc_retain() 和 objc_release() 而不是它们的 Obj-C 等价物 [NSOject retain] 和 [NSObject release]。 ARC 这样做是因为低级 C 函数可以提供额外的优化,例如消除昂贵的 Obj-C 消息发送和取消相邻的自动释放和保留调用。我的问题是,如果我们使用 MRC/ARC 覆盖技术,我们会失去这种优化吗?
  2. 我的第二个问题在某种程度上与我的第一个问题有关。如果目标对象的基类覆盖了它的保留/释放方法,objc_retain()/objc_release() 的运行时行为是什么?我的猜测是这些 C 函数能够弄清楚这里的情况。他们不会执行常规优化(例如消除发送保留/释放消息),实际上他们会恢复到旧方式并实际发送保留/释放消息。

最佳答案

引用文档:

You would implement [the retain] method only if you were defining your own reference-counting scheme. Such implementations must return self and should not invoke the inherited method by sending a retain message to super.

您是否正在实现自己的内存管理系统?不?然后不要覆盖保留或释放。

Apple 还建议不要对所有 Objective-C 代码使用引用计数。您应该使用 ARC。

ASDealloc2MainObject 不会覆盖保留或释放。旧版本可以,但 FaceBook 意识到这是一个糟糕的想法,并更新了他们的代码以使用 ARC。

至于 ARC 的具体行为,答案是“视情况而定”。它有许多不同的行为方式。如果您真的想知道它是如何工作的,请阅读编译器源代码。

您链接到的那篇博文已经过时,根本不应该被信任。 Apple 每 12 个月对编译器进行一次重大更改,这意味着自博客文章撰写以来他们已经这样做了 3 次。由于内存管理是一个性能瓶颈,因此这是他们每年进行最多更改的地方。

向对象发送“保留”或“释放”消息非常慢。 ARC 和 Objective-C 运行时都尽量避免发送消息。创建 Swift 语言的原因之一是完全消除发送消息。 objc_retain() 和 objc_release() 的存在是为了避免向对象发送保留和释放。在某些情况下,他们会这样做,但您不能依赖它。

关于ios - 如果我们覆盖保留/释放方法,我们是否会失去对 ARC 的 objc_retain()/objc_release() 优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27441229/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com