ios在系统代码中注入自己的代码

今天pm提了一个新的需求,需要监听整个程序的事件,在网上查询了下实现的方式。

在stackoverflow中发现了一种实现方式,创建UIApplication的一个子类,在这个子类中覆盖UIApplication中的sendEvent方法,在其中实现自己的功能之后,然后调用UIApplication的sendEvent方法来实现事件分发,代码如下:

子类的名称为MyApplication.

在 main.m 中使用:

  1. return UIApplicationMain(argc, argv, @"MyApplication", @"MyApplicationDelegate");  
然后覆盖[MyApplication sendEvent:]
  1. - (void)sendEvent:(UIEvent*)event {  
  2.     //handle the event (you will probably just reset a timer)  
  3.   
  4.     [super sendEvent:event];  
  5. }  
但是这个问题需要继承UIApplication,感觉不太符合我的要求。所以我就考虑到Category来自己实现sendEvent,然后再其中实现自己功能后,来实现系统的分发,但是在网络上查找了sendEvent的源代码,没有任何发现,突然想到之前使用过的方法替换的方法,就想到了下列方法,具体代码如下:

发现这个方法也可以对其他的系统代码进行代码的注入

  1. void Swizzle(Class c, SEL orig, SEL new) {  
  2.     Method origMethod = class_getInstanceMethod(c, orig);  
  3.    Method newMethod = class_getInstanceMethod(c, new);  
  4.    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))  
  5.        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));  
  6.    else  
  7.     method_exchangeImplementations(origMethod, newMethod);   
  8. }  

然后定义自己的sendEvent方法
  1. - (void)mySendEvent:(UIEvent*)event {  
  2.     //handle the event (you will probably just reset a timer)  
  3.   
  4.     [self mySendEvent:event];  
  5. }  

看到上面方法,直接调用肯定是死循环的,所以不能直接调用的,这个方法是提供给上面的Swizzle进行调用的,这样就将这两个方法进行替换,就是调用下面方法

  1. Swizzle([UIApplication class], @selector(sendEvent:), @selector(mySendEvent:))  

实际就是将这两个方法信息的名称和它们对应的地址进行互换,

1)所以在在系统调用sendEvent的时候实际调用的是mySendEvent

2)mySendEvent方法中调用的mySendEvent实际调用的就是系统的sendEvent

这样就可以实现在sendEvent方法中注入自己需要的代码了。其他的系统方法也可以同样实现注入自己需要的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值