美文网首页
Runtime梳理(五)Swizzle

Runtime梳理(五)Swizzle

作者: 飞奔的小鲨鱼 | 来源:发表于2018-11-25 21:20 被阅读0次

这里暂且不说什么是Swizzle,大家可以自行去网上查找。不知道大家在在实际开发的过程中有没有遇到这样的的问题:有一个A类和一个B类,A类中有一个对象方法a,B类中有一个类方法b,AB类之间无继承关系,当调用A类中的a方法时先调用B类中的B方法。

我们先将这两个类创建出来并实现对应的方法

@interface TestA : NSObject
- (void)testA;
@end
@implementation TestA
- (void)testA{
    NSLog(@"%s",__func__);
}
@end

@interface TestB : NSObject
+ (void)testB;
@end
@implementation TestB
+ (void)testB{
    NSLog(@"%s",__func__);
}
@end

创建NSObject的分类

#import "NSObject+Swizzle.h"
#import <objc/runtime.h>
#import "TestB.h"
#import "TestA.h"
@implementation NSObject (Swizzle)
+ (void)load{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SEL selA = NSSelectorFromString(@"testA");
        Method methodA = class_getInstanceMethod([TestA class], selA);
        
        SEL swizzleA = NSSelectorFromString(@"swizzle_testA");
        Method mSwizzleA = class_getInstanceMethod([self class], swizzleA);
        
        SEL selB = NSSelectorFromString(@"testB");
        Method methodB = class_getClassMethod([TestB class], selB);
        
        IMP impB = class_getMethodImplementation([TestB class], selB);
        IMP impA = class_getMethodImplementation([self class], swizzleA);
        
        
        SEL swizzleB = NSSelectorFromString(@"swizzle_testB");
        Method mSwizzleB = class_getInstanceMethod([self class], swizzleB);
        BOOL resultB = class_addMethod([self class], @selector(swizzle_testB), impB, method_getTypeEncoding(methodB));
        // 交换testB和swizzle_testB方法
        if (resultB) {
            class_replaceMethod([self class], @selector(swizzle_testB), impB, method_getTypeEncoding(methodB));
        }
        else{
            method_exchangeImplementations(mSwizzleB, methodB);
            NSLog(@"bbb");
        }
        
        
        BOOL resultA = class_addMethod([TestA class], selA, impA, method_getTypeEncoding(mSwizzleA));
        // 交换testA和swizzle_testA方法
        if (resultA) {
            NSLog(@"111");
            class_replaceMethod([TestA class], selA, impA, method_getTypeEncoding(mSwizzleA));
        }
        else{
            NSLog(@"222");
            method_exchangeImplementations(methodA, mSwizzleA);
        }
    });
}

- (void)swizzle_testA{
    NSLog(@"%s",__func__);
    [self swizzle_testB];
    [self swizzle_testA];
}

- (void)swizzle_testB{
    NSLog(@"%s",__func__);
    [self swizzle_testB];
}
@end

测试

    TestA  * testa = [TestA new];
    [testa testA];

打印结果

 -[NSObject(Swizzle) swizzle_testA]
 +[TestB testB]
 -[TestA testA]

相关文章

  • Runtime梳理(五)Swizzle

    这里暂且不说什么是Swizzle,大家可以自行去网上查找。不知道大家在在实际开发的过程中有没有遇到这样的的问题:有...

  • iOS开发 HOOK 上篇之 fishhook

    一 HOOK之Method Swizzle 利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法...

  • Runtime第六篇-Method Swizzling

    Method Swizzling被称为runtime的黑魔法。swizzle在英文中的本意是“搅和”。 Metho...

  • 神奇的fishhook

    fishhook介绍 我们都知道OC的Runtime里的Method Swizzle可以动态改变SEL(方法编号)...

  • iOS Method Swizzle黑魔法小记

    本文主要内容为用runtime实现Swizzle,即调换两个方法的实现 一点iOS runtime的基本知识 Ob...

  • 《iOS 逆向》010-Hook简单使用

    iOS中HOOK技术的几种方式 1、Method Swizzle 利用OC的Runtime特性,动态改变SEL(方...

  • 5.MachO文件

    Method Swizzle 利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关...

  • iOS逆向与安全2.3:代码注入Hook方式

    Method Swizzle 利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关...

  • HOOK技术

    iOS中HOOK技术的几种方式 Method Swizzle利用OC的Runtime特性,动态改变SEL(方法编号...

  • KVO的底层原理

    Key-Value Observing 键值对观察者模式 基于OC强大的Runtime机制和isa-swizzle...

网友评论

      本文标题:Runtime梳理(五)Swizzle

      本文链接:https://www.haomeiwen.com/subject/iifmqqtx.html