Objective C 中类别是如何实现的?

发布于 2024-11-29 08:19:54 字数 270 浏览 3 评论 0原文

作为一名程序员,我知道如何使用类别,但我很好奇它们是如何实现的。编译器是否将它们编译为对 class_replaceMethod 来自静态初始值设定项?谢谢。

I know how to use categories as a programmer, but I'm curious how they are implemented. Does the compiler compile them into calls to class_replaceMethod from a static initializer? Thanks.

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

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

发布评论

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

评论(3

放低过去 2024-12-06 08:19:54

关于主题的新答案。

每个类都有一个方法列表,在进行方法查找时,会从头到尾扫描方法列表。如果没有找到方法,则扫描超类列表等,直到到达根类。找到的方法会被缓存,以便下次更快地查找。

将类别加载到类上时,类别方法列表将添加到现有列表中,并刷新缓存。由于列表是按顺序搜索的,这意味着类别方法将在下次搜索时在原始方法之前找到。

当第一次访问类时,类别的设置是从静态数据延迟完成的。如果加载带有可执行代码的包,则可以重新完成。

简而言之,它比 class_replaceMethod() 更底层一些。

New answer on topic.

Each class has a list of methods, when doing a method lookup the method list is scanned from beginning to end. If no method is found the superclass' list is scanned, etc. until reaching the root class. Found methods are cached for faster lookup next time.

When loading a category onto a class the categories method list is prepended to the existing list, and caches are flushed. Since the list is searched sequentially this means that the categories method will be found before the original method on next search.

This setup of categories is done lazily, from static data, when the class is first accessed. And can be re-done if loading a bundle with executable code.

In short it is a bit more low level than class_replaceMethod().

我三岁 2024-12-06 08:19:54

您可以从这里找到您想了解的有关它们如何工作的所有内容。

http://opensource.apple.com/source /objc4/objc4-493.9/runtime/objc-runtime-new.mm

运行时是完全开源的。

You can find everything you ever wanted to know about how they work from here.

http://opensource.apple.com/source/objc4/objc4-493.9/runtime/objc-runtime-new.mm

The runtime is fully open source.

迷荒 2024-12-06 08:19:54

类别没有任何特殊的实现,它们实际上本质上是无效的实现。

这些协议在运行时充当类的标记。您可以使用class_copyProtocolList()从运行时获取类遵循的协议列表。有一个同级 protocol_copyProtocolList() 函数用于获取协议所遵循的协议。

请注意,这些方法仅返回该特定类或协议的协议列表。不是来自超类或其他协议的引用。这意味着运行时的实际查找将是昂贵的。相反,使用 class_conformsToProtocol()(或 protocol_conformsToProtocol())来查询一致性,这些方法可以缓存结果。

在实践中,在运行时查询一致性很少是一个好主意。协议一致性通过编译器的警告进行验证,如果开发人员选择忽略这些警告,那么……这是他们的选择。

Categories do not have any special implementation, they are in fact by nature void of implementation.

The protocols acts as markers on classes at run-time. You can use class_copyProtocolList() to get the list of protocols that a class conforms to from the runtime. There is a sibling protocol_copyProtocolList() function to get the protocol that a protocol conforms to.

Do notice that these methods only returns a list of protocols for this particular class or protocol. Not from superclasses, or other protocols by reference. This means that the actual lookup at run-time will be expensive. Instead use class_conformsToProtocol() (or protocol_conformsToProtocol()) to query for conformance, these methods can cache the result.

In practice querying for conformance at run-time is seldom a good idea. The protocol conformance is validated with warnings by the compiler, if the developer chooses to ignore these warning, well... it's their choice let them.

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