In the absence of a class implementation of the source code, want to change the implementation of one of the methods, in addition to inheriting it rewrite, and the use of class name method of violence preemptive, there is a method of exchange
Principle of method Exchange: Invoking a method in OC is actually sending a message to an object, and the only way to find the message is by selector's name. By using the dynamic characteristics of OC, the realization of the Selector method can be realized at runtime, and the purpose of the method hook is achieved.
Each class has a list of methods that are stored in Selector's name and method implementation mapping, and IMP is a bit like a function pointer, pointing to a concrete method implementation.
can use Method_exchanggeimplementations to exchange two methods of IMP
You can use Class_replacemethod to modify the class
You can use Method_setimplementation to directly set up an imp for a method
In the final analysis, the exchange is a selector imp.
Method swizzling Practice
For example, I'd like to hook up Nsarray's Lastobject method in just two steps.
First step: Give Nsarray a lastobject of my own
[CPP] View plaincopyprint?
#import "Nsarray+swizzle.h"
@implementation Nsarray (Swizzle)
-(ID) mylastobject
{
ID ret = [self mylastobject];
NSLog (@ "********** mylastobject ***********");
return ret;
}
@end
At first glance, is this not recursive? Don't forget that this is the selector,[self mylastobject [self lastobject] that we are going to switch to IMP] will do.
Step Two: Exchange Imp
[CPP] View plaincopyprint?
#import <objc/runtime.h>
#import "Nsarray+swizzle.h"
int main (int argc, char *argv[])
{
@autoreleasepool {
Method Ori_method = Class_getinstancemethod ([Nsarray class], @selector (lastobject));
Method My_method = Class_getinstancemethod ([Nsarray class], @selector (mylastobject));
Method_exchangeimplementations (Ori_method, My_method);
Nsarray *array = @[@ "0", @ "1", @ "2", @ "3"];
NSString *string = [array lastobject];
NSLog (@ "TEST RESULT:%@", string);
return 0;
}
}
Package of Method swizzling
[CPP] View plaincopyprint?
//
RNSWIZZLE.M
Methodswizzle
#import "RNSwizzle.h"
#import <objc/runtime.h>
@implementation NSObject (Rnswizzle)
+ (IMP) Swizzleselector: (SEL) Origselector
Withimp: (IMP) Newimp {
Class class = [self class];
Method Origmethod = Class_getinstancemethod (class,
Origselector);
IMP origimp = method_getimplementation (Origmethod);
if (!class_addmethod (self, origselector, Newimp,
Method_gettypeencoding (Origmethod)))
{
Method_setimplementation (Origmethod, newimp);
}
return origimp;
}
@end
After defining the new method, you need to figure out when to interact with the system's methods? A: Since it is to add additional functionality to the system's methods, in other words, we will use our own defined methods to replace the system in the future, so when the program starts, it requires the ability to use its own defined function methods. Say here: We have to figure out two ways: + (void) Initialize (the method will be called when the class is first called) + (void) + (only once in the run of the program) Load (This method is called when the program starts, in other words, the load method is called whenever the program starts, and is only called once in the entire program) + (void) load {/* Self:uiimage who's the thing, who begins 1. Send Message (object: OBJC) 2. Method of registration (method number: SEL) 3. Method of interaction (methods: Method) 4. Get Method (class: Class) Meth Od: Method Name gets method, method saved to class: Gets which class method SEL: Gets which method imagename*///get ImageName: Address of method Method Imagenamemethod = Class_getclassmethod (self, @ Selector (imagenamed:)); //get Wg_imagewithname: Address method Wg_imagewithnamemethod = Class_getclassmethod (self, @selector (wg_imagewithname:)); //Interchange method address, equivalent to interchange implementation mode Method_exchangeimplementations (Imagenamemethod, Wg_ Imagewithnamemethod)}
Run-time Method Exchange