使用Runtime修改UILabel的setText方法

1、新建一个UILabel的Category(UILabel+AOP),添加一个桥梁方法

// 设置一个桥梁方法
- (void)setBrige:(NSString *)text
{
    
}

2、使用runtime得到SEL、Method、IMP

    // 获取UILabel setText的selector、method、IMP
    SEL setTextSelector = @selector(setText:);
    Method setTextMethod = class_getInstanceMethod(clazz, setTextSelector);
    IMP setTextIMP = method_getImplementation(setTextMethod);
    
    // 获取替换原setText实现方法的hs_setText selector、method、IMP
    SEL hs_setTextSelector = @selector(hs_setText:);
    Method hs_setTextMethod = class_getInstanceMethod(clazz, hs_setTextSelector);
    IMP hs_setTextIMP = method_getImplementation(hs_setTextMethod);
    
    // 作为桥梁的方法
    SEL setBrigeSelector = @selector(setBrige:);

3、先将桥梁方法的IMP 替换为UILabel的setText的IMP

class_replaceMethod(clazz, setBrigeSelector, setTextIMP, method_getTypeEncoding(setTextMethod));

4、再将UILabel的setText的IMP 替换为hs_setText

class_replaceMethod(clazz, setTextSelector, hs_setTextIMP, method_getTypeEncoding(hs_setTextMethod));

5、UILabel+AOP.m 完整代码

#import "UILabel+AOP.h"
#import <objc/runtime.h>

@implementation UILabel (AOP)

- (void)swizzleIMP
{
    Class clazz = [self class];
    
    // 获取UILabel setText的selector、method、IMP
    SEL setTextSelector = @selector(setText:);
    Method setTextMethod = class_getInstanceMethod(clazz, setTextSelector);
    IMP setTextIMP = method_getImplementation(setTextMethod);
    
    // 获取替换原setText实现方法的hs_setText selector、method、IMP
    SEL hs_setTextSelector = @selector(hs_setText:);
    Method hs_setTextMethod = class_getInstanceMethod(clazz, hs_setTextSelector);
    IMP hs_setTextIMP = method_getImplementation(hs_setTextMethod);
    
    // 作为桥梁的方法
    SEL setBrigeSelector = @selector(setBrige:);
//    Method setBrigeMethod = class_getInstanceMethod(clazz, setBrigeSelector);
//    IMP setBrigeIMP = method_getImplementation(setBrigeMethod);
    
    // 方法1、交换
    method_exchangeImplementations(setTextMethod, hs_setTextMethod);
    
    // 方法2、替换
    // 将setBrige的IMP替换为setText的IMP
//    class_replaceMethod(clazz, setBrigeSelector, setTextIMP, method_getTypeEncoding(setTextMethod));
    
    // 将setText的IMP 替换为 hs_setText的IMP
//    class_replaceMethod(clazz, setTextSelector, hs_setTextIMP, method_getTypeEncoding(hs_setTextMethod));

}

+ (void)initialize
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        id obj = [[self alloc] init];
        [obj swizzleIMP];
    });
}

- (void)hs_setText:(NSString *)text
{
    // 方法1
    NSLog(@"执行setText之前");
    text = [NSString stringWithFormat:@"hs-%@",text];
    [self hs_setText:text];
    NSLog(@"执行setText之后");
    text = [NSString stringWithFormat:@"%@--hs",text];
    
    // 方法2
//    [self setBrige:[NSString stringWithFormat:@"hs-%@",text]];
}

// 设置一个桥梁方法
- (void)setBrige:(NSString *)text
{
    
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容