“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”
Methods exchange
At run time, the class maintains a list of methods that address the proper handling of messages. The method list maps the method name to the Implementation of the associated method, where the key value is the method name Selector(SEL) and the value points to the Implementation’s function pointer Implementation(IMP).
In the OC Runtime feature, the method of calling an object is to send a message to the object. Find the corresponding SEL from the method list by looking up the list of methods that receive the message object. This SEL corresponds to an IMP. Find the corresponding method call through this IMP. Method swapping modifies the mapping between SEL and IMP in the class’s method list so that an existing SEL maps to another IMP
Method interchange
-
About +(void)initialize and +(void) Load
+(void)initialize
This method is called the first time a class is called, and only once during the entire program run+ (void)load
This method is called when the program is started. In other words, the load method is called as soon as the program is started, and only once during the entire program run
-
Add a Category to the class of the method you want to swap, and then add the method swap to the + (void)load method of the Category
-
Obtain method address
Method class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name) Copy the code
-
Exchange method address, equivalent to exchange implementation
void method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) Copy the code
Method interchange example
Usage scenario: If you need to extend a feature without changing the original code, you can use method swapping
Start by adding a Category to the class of the method you want to swap
@interface NSURL (ExchangeMethod)
@end
#import "NSURL+ExchangeMethod.h"
#import <objc/runtime.h>
@implementation NSURL (ExchangeMethod)
// Called when the class is loaded
+ (void)load{
NSLog(@"load");
// Get the method address
Method urlWithStr = class_getClassMethod([NSURL class], @selector(URLWithString:));
Method XYURLWithStr = class_getClassMethod([NSURL class], @selector(XYURLWithStr:));
// Switch method address, equivalent to switch implementation
method_exchangeImplementations(urlWithStr,XYURLWithStr);
}
// The system method URLWithString cannot be overridden in the class because it overwrites the system functionality and cannot call super in the class.
+ (instancetype)XYURLWithStr:(NSString*)str{
/** ('XYURLWithStr'); /** ('XYURLWithStr'); Note: there is no recursive operation. */
NSURL *url = [NSURL XYURLWithStr:str];// Call the system method implementation
if (url == nil){
NSLog(@"Perform custom links");
}
return url;
}
@end
Copy the code
A function call
#import "ViewController.h"
#import "NSURL+ExchangeMethod.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"Http://www.baidu.com/ error"];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
}
@end
Copy the code