Method class_getInstanceMethod(Class aClass, SEL aSelector) { CHECK_ARG(aClass); CHECK_ARG(aSelector); // If the class has a dtable installed, then we can use the fast path if (classHasInstalledDtable(aClass)) { // Do a dtable lookup to find out which class the method comes from. struct objc_slot *slot = objc_get_slot(aClass, aSelector); if (NULL == slot) { slot = objc_get_slot(aClass, sel_registerName(sel_getName(aSelector))); if (NULL == slot) { return NULL; } } // Now find the typed variant of the selector, with the correct types. aSelector = slot->selector; // Then do the slow lookup to find the method. return class_getInstanceMethodNonrecursive(slot->owner, aSelector); } Method m = class_getInstanceMethodNonrecursive(aClass, aSelector); if (NULL != m) { return m; } return class_getInstanceMethod(class_getSuperclass(aClass), aSelector); }
static void objc_updateDtableForClassContainingMethod(Method m) { Class nextClass = Nil; void *state = NULL; SEL sel = method_getName(m); while (Nil != (nextClass = objc_next_class(&state))) { if (class_getInstanceMethodNonrecursive(nextClass, sel) == m) { objc_update_dtable_for_class(nextClass); return; } } }
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) { Method method = class_getInstanceMethodNonrecursive(cls, name); IMP old; if (method == NULL) { class_addMethod(cls, name, imp, types); return NULL; } old = (IMP) method->method_imp; method->method_imp = (objc_imp_gnu) imp; return old; }
Method class_getInstanceMethod(Class aClass, SEL aSelector) { Method method = class_getInstanceMethodNonrecursive(aClass, aSelector); if (method == NULL) { // TODO: Check if this should be NULL or aClass Class superclass = class_getSuperclass(aClass); if (superclass == NULL) { return NULL; } return class_getInstanceMethod(superclass, aSelector); } return method; }
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) { if (Nil == cls) { return (IMP)0; } SEL sel = sel_registerTypedName_np(sel_getName(name), types); Method method = class_getInstanceMethodNonrecursive(cls, sel); if (method == NULL) { class_addMethod(cls, sel, imp, types); return NULL; } IMP old = (IMP)method->imp; method->imp = imp; if (objc_test_class_flag(cls, objc_class_flag_resolved)) { objc_update_dtable_for_class(cls); } return old; }