Artifice refers to a skill and a product that is too kit and useless.
IMS refers to Instance method swizzling, which is confused by instance methods.
The next section of code is an example of a instance method swizzling and a method swizzling:
// Man.m
-(void) run
{
NSLog (@ "% s,% @", __func__, _name);
}
-(void) jump
{
NSLog (@ "% s,% @", __func__, _name);
}
-(void) handsUp
{
NSLog (@ "% s,% @", __func__, _name);
}
-(void) handsDown
{
NSLog (@ "% s,% @", __func__, _name);
}
// ViewController.m
-(void) viewDidLoad {
...
Man * a = [Man manWithName: @ "a"];
Man * b = [Man manWithName: @ "b"];
[self swizzleInstanceMethodWithInstance: a originalSel: @selector (run) replacementSel: @selector (jump)];
[self swizzleInstanceMethodWithClass: [Man class] originalSel: @selector (handsUp) replacementSel: @selector (handsDown)];
[a run];
[b run];
[a handsUp];
[b handsUp];
}
// The output is
2015-03-14 23: 53: 39.832 testRuntime [2196: 629365]-[Man jump], a
2015-03-14 23: 53: 39.833 testRuntime [2196: 629365]-[Man run], b
2015-03-14 23: 53: 39.833 testRuntime [2196: 629365]-[Man handsDown], a
2015-03-14 23: 53: 39.833 testRuntime [2196: 629365]-[Man handsDown], b
Why is the Run method only replaced with object A, and the Handsup method is all replaced?
Let's start by looking at how the common method swizzling is implemented.
-(void) swizzleInstanceMethodWithClass: (Class) clazz originalSel: (SEL) original replacementSel: (SEL) replacement
{
Method a = class_getInstanceMethod (clazz, original);
Method b = class_getInstanceMethod (clazz, replacement);
// class_addMethod adds a new method to the class
if (class_addMethod (clazz, original, method_getImplementation (b), method_getTypeEncoding (b)))
{
// Replace the implementation pointer of the class method
class_replaceMethod (clazz, replacement, method_getImplementation (a), method_getTypeEncoding (a));
}
else
{
// exchange implementation pointers for 2 methods
method_exchangeImplementations (a, b);
}
}
Instance method Swizzling is a method similar to KVO.
Dynamically add a class MySubClass inherit from the original class, then modify the Isa for object A to be the new class, and then replace the method of the new class.
- (void)swizzleInstanceMethodWithInstance:(id)object originalSel:(SEL)original replacementSel:(SEL)replacement
{
Class newClass = objc_allocateClassPair([object class], "MySubclass", 0);
objc_registerClassPair(newClass);
Method a = class_getInstanceMethod(newClass, original);
Method b = class_getInstanceMethod([object class], replacement);
if (class_addMethod(newClass, original, method_getImplementation(b), method_getTypeEncoding(b))) {
class_replaceMethod(newClass, replacement, method_getImplementation(a), method_getTypeEncoding(a));
}
else
{
method_exchangeImplementations(a, b);
}
object_setClass(object, newClass);
}
OBJECTIVE-C Kit Kat Kinky Technology--ims