1. class_getInstanceMethod
1. api说明
runtime.h /** * Returns a specified instance method for a given class. * * @param cls The class you want to inspect. * @param name The selector of the method you want to retrieve. * * @return The method that corresponds to the implementation of the selector specified by * \e name for the class specified by \e cls, or \c NULL if the specified class or its * superclasses do not contain an instance method with the specified selector. * * @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not. */ OBJC_EXPORT Method _Nullable class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name) OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
由Api说明可知,当前类查找不到该SEL时,会在父类中查找
2. Runtime 源码
/*********************************************************************** * class_getInstanceMethod. Return the instance method for the * specified class and selector. **********************************************************************/ Method class_getInstanceMethod(Class cls, SEL sel) { if (!cls || !sel) return nil; // This deliberately avoids +initialize because it historically did so. // This implementation is a bit weird because it's the only place that // wants a Method instead of an IMP. Method meth; meth = _cache_getMethod(cls, sel, _objc_msgForward_impcache); if (meth == (Method)1) { // Cache contains forward:: . Stop searching. return nil; } else if (meth) { return meth; } // Search method lists, try method resolver, etc. lookUpImpOrForward(nil, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER); meth = _cache_getMethod(cls, sel, _objc_msgForward_impcache); if (meth == (Method)1) { // Cache contains forward:: . Stop searching. return nil; } else if (meth) { return meth; } return _class_getMethod(cls, sel); }
由源码得知,Runtime会先在类的方法缓存列表中查找,然后在类的方法列表中查找