我知道如何使用类别作为程序员,但我很好奇它们是如何实现的。编译器是否将它们编译为从静态初始化程序调用{{3}}?感谢。
答案 0 :(得分:9)
关于主题的新答案。
每个类都有一个方法列表,在进行方法查找时,从头到尾扫描方法列表。如果没有找到方法,则扫描超类列表等,直到到达根类。缓存找到的方法,以便下次更快地查找。
将类别加载到类时,类别方法列表预先到现有列表,并刷新缓存。由于列表是按顺序搜索的,这意味着在下次搜索原始方法之前将找到categories方法。
这种类别设置是在第一次访问类时从静态数据中懒洋洋地完成的。如果使用可执行代码加载包,则可以重新完成。
简而言之,它比class_replaceMethod()
低一点。
答案 1 :(得分:3)
你可以从这里找到你想知道的关于它们如何工作的一切。
http://opensource.apple.com/source/objc4/objc4-493.9/runtime/objc-runtime-new.mm
运行时是完全开源的。
答案 2 :(得分:0)
类别没有任何特殊的实现,实际上它们实际上没有实现。
协议在运行时充当类的标记。您可以使用class_copyProtocolList()
从运行时获取类符合的协议列表。有一个兄弟protocol_copyProtocolList()
函数来获取协议符合的协议。
请注意,这些方法仅返回此特定类或协议的协议列表。不是来自超类或其他协议的引用。这意味着在运行时实际查找将是昂贵的。而是使用class_conformsToProtocol()
(或protocol_conformsToProtocol()
)来查询一致性,这些方法可以缓存结果。
实际上,在运行时查询一致性很少是一个好主意。如果开发人员选择忽略这些警告,那么协议一致性将通过编译器的警告进行验证,那么......他们的选择就是让他们这样做。