runtime 应用之- 拦截系统类方法

本文介绍如何使用Objective-C运行时API中的method_exchangeImplementations函数,实现UIViewController的viewDidLoad方法的重写与调用。通过替换系统方法的实现,可以在系统方法调用前执行自定义逻辑,如KVO的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们有时候需要拦截hook 下系统的方法,在系统方法被调用之前先调用我们的方法,然后再调用系统的方法,这样我们可以做些额外的事情,比如KVO 的实现也用到了类似的方法。

下面我们实践下 ,我们重写 UIViewController 的 viewDidLoad 方法, 替换掉 系统的viewDidLoad 后,我们再调用系统的viewDidLoad的实现。

主要用到的函数: method_exchangeImplementations

代码如下:

+(void) initialize {
    
    SEL originLoadSel = @selector(viewDidLoad);
    SEL myViewLoadSel = @selector(myViewDidLoad);
    
    Method originLoadMethod = class_getInstanceMethod([self class], originLoadSel);
    Method myLoadMethod = class_getInstanceMethod([self class], myViewLoadSel);
    
    method_exchangeImplementations(originLoadMethod, myLoadMethod);
}
- (void) myViewDidLoad {
    NSLog(@"my custom ViewDidLoad");
    
    //call real viewDidLoad
    [self myViewDidLoad];
}
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    NSLog(@"origin viewDidLoad");
}

运行代码,可以看到 先输出: my custom ViewDidLoad ,  然后再输出 origin viewDidLoad. 

原理也很简单:就是替换了 viewDidLoad 和  myViewDidLoad 这两个 Method 的 SEL 所对应的 IMP 实现,  viewDidLoad 的 SEL 被替换为了 myViweDidLoad 这个Method 的 IMP , 反之,  myViewDidLoad 的 Method 的 IMP 对应了 系统的原生 viewDidLoad的IMP。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值