tip
- I want to know what methods are inserted into the cache
- Here you want to open the hidden folder display Shift + Command +.
- What did you do when you started studying this approach
Let’s see if this works
- 1. Create a class that declares an unimplemented method
- 2. Implement this method in a.m file.
- (id)forwardingTargetForSelector:(SEL)aSelector{
NSLog(@"%s - %@",__func__,NSStringFromSelector(aSelector));
return nil;
}
Copy the code
- 3. This method is called even though the result is an error
- 4. Now create another class and implement this method.
- 5. Import this class and return the value of this method as a new object
- 6. The result is a successful implementation of another class method call
- OC calls the method through sel-> IMP
- 1. Objc_msgSend searches the cache
- 2. Search methodList slowly
- 3. Dynamic method resolution
- 4. The Runtime mechanism lets other classes call methods with the same method name to do this.
Fast forward
// Fast forward
- (id)forwardingTargetForSelector:(SEL)aSelector{
NSLog(@"%s - %@",__func__,NSStringFromSelector(aSelector));
return nil;
}
- (id)forwardingTargetForSelector:(SEL)aSelector{
return [LGStudent alloc];
}
Copy the code
- Add that the class we return does not have an implementation of this method, so slow forwarding is required
methodSignatureForSelector
Methods withforwardInvocation
use
Slowly forward
//// Slow forwarding
// Return a method signature
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSLog(@"%s - %@",__func__,NSStringFromSelector(aSelector));
if (aSelector == @selector(sayHello)) {
// Return a method signature
return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
}
return [super methodSignatureForSelector:aSelector];
}
Copy the code
- This method is not implemented for the time being
- (void)forwardInvocation:(NSInvocation *)anInvocation{
NSLog(@ % @ - % @ "",anInvocation.target,NSStringFromSelector(anInvocation.selector));
}
Copy the code
- Found that the program did not crash while logging the method called by the object. This can be used as a collection of error logs.
- Here tip us if this method to implement will need to rewrite methodSignatureForSelector
- (void)forwardInvocation:(NSInvocation *)anInvocation{
// NSLog(@"%@ - %@",anInvocation.target,NSStringFromSelector(anInvocation.selector));
LGStudent *s = [LGStudent alloc];
// Determine that self can handle this method
if ([self respondsToSelector:anInvocation.selector]) {
[anInvocation invoke]; // Invoke directly
}else if ([s respondsToSelector:anInvocation.selector]){
// Determine which class can handle this method
[anInvocation invokeWithTarget:s];
}else{
// There is a crash
NSLog(@"%s - %@",__func__,NSStringFromSelector(anInvocation.selector)); }}Copy the code
Explore ideas, the road is bumpy, entry to give up.
- 1. Bt print to view the compilation stack flow and find the target in CoreFoundation
- 2. Failed to search for CF source code
- 3.CoreFoundation Find the CoreFoundation open source code
- 4. Select one to download
Finally found a CoreFoundation open source dynamic library, hahahahahahahaha I will not look for. The teacher gave, the net search should be some.
Disassembly process
- Open the executable file to Hopper
- Enter theforwarding
- So this is an error of judgment going to loc_64a67 and ignoring it
- The structure is stored in the RAX register. rax = _objc_msgSend(rdi,r14);
- Continue to run to find the underlying message receiver