Small valley bottom exploration collection

  • I mentioned it in the last blog (slow lookup analysis)Dynamic method resolution. Today we have a waveDynamic method resolution!!!!!

1. Identify key methods

    1. We already know that — when looking up (lookUpImpOrForward), in the end did not find imp, gave a chance to remedy ~
	// No implementation found. Try method resolver once.
	if (slowpath(behavior & LOOKUP_RESOLVER)) {
        behavior ^= LOOKUP_RESOLVER;
        return resolveMethod_locked(inst, sel, cls, behavior);
    }
Copy the code

Look directly also don’t know what this is, so we have to develop the habit of reading notes.

  • Comment meaning: No implementation found. Attempt to call the method at resolve once

    1. Let’s go in and scan it and focus on the analysis (after all, reading every line at first feels like folly. I used to be. 😆))

    1. We observed two core approaches:resolveInstanceMethod,resolveClassMethod!

One is solving instance methods and the other is solving class methods.

2. Exploration and analysis

Dynamic method resolution includes: object dynamic method resolution, class dynamic method resolution

2.1. Dynamic method resolution for object methods

resolveInstanceMethod

2.1.1. Verify the conjecture

    1. When we analyze the method, we first need to find the key code, which line determines the role, I drew a wave graph analysis (positioning from back to front)

    1. Now that we have this key thing, let’s search, where is this called

    1. This returns NO, it feels like nothing is being processed
    1. Then I will drop a declaration, no implementation method!! (As we all know, to go to the time of recovery, it is not found before)

        XGTest *test = [XGTest alloc];
        Class tClass = [test class];
        [test say5];
Copy the code

    1. Really can go ~~~~!! So let’s take a look at the stack

It’s the same process we used to analyze

2.1.2. Method application

Here’s an idea: if we rewrite this method and associate SEL with an IMP, is there no problem in theory?

Have brother say: you also know is theory!! I’m definitely going to practice it

If a class has a classification, the classification method is called first (same method). (I won’t explain that in this blog.)

    1. We createNSObjectClassification, make a wave (😆)
    1. Create it and log it to prove he was there.

    1. Look at the output

He has been in ~ ~ ~

    1. Our thinking:selThere is no one can’t know the correspondingimpSo it collapses. Let’s give him a ~
#import <objc/message.h>

- (void)instanceMethodFix{
    NSLog(@"%s",__func__);
}

+ (BOOL)resolveInstanceMethod:(SEL)sel{
    NSLog(@"%s--%@",__func__,NSStringFromSelector(sel));
    if (sel == @selector(say5)){
        IMP imp = class_getMethodImplementation(self.@selector(instanceMethodFix));
        Method method = class_getInstanceMethod(self.@selector(instanceMethodFix));
        const char * type = method_getTypeEncoding(method);
        return class_addMethod(self, sel, imp, type);
    }
    return NO;
}
Copy the code

We get the imp of the instanceMethodFix method and associate sel of Say5 with it, guys. Let me run it.

He’s not falling apart!! He’s not falling apart!! He’s not falling apart!!

    1. Bottom line: Our analysis was correct, and not finding an apple gave him a chance to fix it

Walk to this method inside explain method did not find — as to how to use, be about to see you ~

2.2. Dynamic method resolution for class methods

After studying the object’s dynamic method resolution, the class is simpler

    1. We find the core of this approach

    1. Start with a wave of code that calls class methods
[XGTest say6];// The method is not implemented
Copy the code
    1. We can continue to create methods in categories! Then see if it’s the same principle!
- (void)classMethodFix{
    NSLog(@"%s",__func__);
}

+ (BOOL)resolveClassMethod:(SEL)sel{
    NSLog(@"%s--%@",__func__,NSStringFromSelector(sel));
    if (sel == @selector(say6)) {
        IMP imp = class_getMethodImplementation(self.@selector(classMethodFix));
        Method method = class_getClassMethod(self.@selector(classMethodFix));
        const char *type = method_getTypeEncoding(method);
        return class_addMethod(self, sel, imp, type);
    }
    return NO;
}
Copy the code

** We move to print a wave, oh my god! Crash!! 支那

    1. At this point, it’s time to introduce a wave of ISA bitmaps

    1. In fact, careful brothers, should also found a problem: is dealing withresolveClassMethodwhen

Guys, I created the classification of NSObject ~ (haha 😆, also don’t know who learned this naughty character ~). As for how to change the correct you should also know (some things can not be said too clearly, otherwise it will discourage brothers from exploring ~)

    1. Well, that way we can actually do itresolveInstanceMethodIt’s all done
- (void)instanceMethodFix{
    NSLog(@"%s",__func__);
}

+ (BOOL)resolveInstanceMethod:(SEL)sel{
    NSLog(@"%s--%@",__func__,NSStringFromSelector(sel));
    if (sel == @selector(say5)){
        IMP imp = class_getMethodImplementation(self.@selector(instanceMethodFix));
        Method method = class_getInstanceMethod(self.@selector(instanceMethodFix));
        const char * type = method_getTypeEncoding(method);
        return class_addMethod(self, sel, imp, type);
    }else if (sel == @selector(say6)){
        IMP imp = class_getMethodImplementation(self.@selector(instanceMethodFix));
        Method method = class_getInstanceMethod(self.@selector(instanceMethodFix));
        const char * type = method_getTypeEncoding(method);
        return class_addMethod(self, sel, imp, type);
    }
    return NO;
}
Copy the code

Ha ha, found OK ~

The best way to record it is for brothers to explore a wave of ~👌