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 requiredmethodSignatureForSelectorMethods withforwardInvocationuse

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