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
-
- We already know that — when looking up (
lookUpImpOrForward
), in the end did not find imp, gave a chance to remedy ~
- We already know that — when looking up (
// 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
-
- 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. 😆))
-
- We observed two core approaches:
resolveInstanceMethod
,resolveClassMethod
!
- We observed two core approaches:
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
-
- 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)
-
- Now that we have this key thing, let’s search, where is this called
-
- This returns NO, it feels like nothing is being processed
-
- 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
-
- 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.)
-
- We create
NSObject
Classification, make a wave (😆)
- We create
-
- Create it and log it to prove he was there.
-
- Look at the output
He has been in ~ ~ ~
-
- Our thinking:
sel
There is no one can’t know the correspondingimp
So it collapses. Let’s give him a ~
- Our thinking:
#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!!
-
- 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
-
- We find the core of this approach
-
- Start with a wave of code that calls class methods
[XGTest say6];// The method is not implemented
Copy the code
-
- 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!! 支那
-
- At this point, it’s time to introduce a wave of ISA bitmaps
-
- In fact, careful brothers, should also found a problem: is dealing with
resolveClassMethod
when
- In fact, careful brothers, should also found a problem: is dealing with
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 ~)
-
- Well, that way we can actually do it
resolveInstanceMethod
It’s all done
- Well, that way we can actually do it
- (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 ~👌