Objective C 中的类别是如何实现的?
Posted
技术标签:
【中文标题】Objective C 中的类别是如何实现的?【英文标题】:How are categories implemented in Objective C? 【发布时间】:2011-08-11 12:57:29 【问题描述】:作为程序员,我知道如何使用类别,但我很好奇它们是如何实现的。编译器是否将它们编译为从静态初始化程序对class_replaceMethod 的调用?谢谢。
【问题讨论】:
【参考方案1】:关于主题的新答案。
每个类都有一个方法列表,在进行方法查找时,方法列表会从头到尾扫描。如果没有找到方法,则扫描超类的列表等,直到到达根类。缓存找到的方法以便下次更快查找。
当将类别加载到类中时,类别方法列表会添加到现有列表中,并且缓存会被刷新。由于列表是按顺序搜索的,这意味着类别方法将在下一次搜索时在原始方法之前找到。
这种类别的设置是在第一次访问类时从静态数据中懒惰地完成的。如果加载带有可执行代码的包,则可以重新完成。
总之比class_replaceMethod()
低一点。
【讨论】:
在第一次使用类别之前,是否有一个“初始化”类别的好地方?我试过+initialize
,但它似乎在第一次调用类别类时就被调用了,所以初始化类别可能是不必要的,更重要的是,可能会导致无限循环。【参考方案2】:
您可以从这里找到所有您想知道的关于它们如何工作的信息。
http://opensource.apple.com/source/objc4/objc4-493.9/runtime/objc-runtime-new.mm
运行时完全开源。
【讨论】:
谢谢,这很有用。我希望我能接受多个答案,所以我将只支持您的评论。【参考方案3】:类别没有任何特殊的实现,它们实际上本质上是没有实现的。
协议在运行时充当类的标记。您可以使用class_copyProtocolList()
从运行时获取类符合的协议列表。有一个兄弟protocol_copyProtocolList()
函数来获取一个协议所遵循的协议。
请注意,这些方法仅返回此特定类或协议的协议列表。不是来自超类或其他协议的引用。这意味着在运行时的实际查找会很昂贵。而是使用class_conformsToProtocol()
(或protocol_conformsToProtocol()
)来查询一致性,这些方法可以缓存结果。
实际上,在运行时查询一致性很少是一个好主意。协议一致性由编译器通过警告来验证,如果开发人员选择忽略这些警告,那么......这是他们的选择。
【讨论】:
你为什么要谈论协议?它们与类别完全不同? @Joshua Weinberg - 没错,我完全把自己搞砸了。我 100% 确定问题是协议。该死,在正确的情况下,我会喜欢我的答案。以上是关于Objective C 中的类别是如何实现的?的主要内容,如果未能解决你的问题,请参考以下文章
在 Objective-C 中使用类别的私有方法:从子类调用 super
如何在 Swift 中调用 Objective-C 类别方法