Open ascendQing opened 6 years ago
是这样的,拿UnrecognizedSelector类型防护为例子,如果之前有开启过防护的话,那么肯定会执行以下的代码: BMP_EXChangeInstanceMethod([NSObject class], @selector(forwardingTargetForSelector:), [NSObject class], @selector(BMP_forwardingTargetForSelector:)); 这时候,NSObject原有的forwardingTargetForSelector方法会被我们自己写的BMP_forwardingTargetForSelector方法替代,从而可以在我们自己的方法中执行一些保护措施,当关闭防护的时候,会首先通过imp链表判断下这个防护是不是开启过,如果没有开启过,就没有关闭的必要,如果有开启过的话,那么它会再执行一次交换操作,还是执行以下代码: BMP_EXChangeInstanceMethod([NSObject class], @selector(forwardingTargetForSelector:), [NSObject class], @selector(BMP_forwardingTargetForSelector:)); 但是这时候NSObject的forwardingTargetForSelector方法对应的imp其实已经跟NSObject分类中的BMP_forwardingTargetForSelector的imp发生互换了,此时再执行一次交换操作的话,相当于负负得正,又恢复原状了。
谢谢作者回复,昨晚上想明白了这个问题了。但是实际测试的时候,发现用block回调的方法打开防护后,再去关闭防护,然后再用block回调的方法打开防护,之后拦截UnrecognizedSelector类型就不起作用了。(防护类型都是所有类型)。暂时没有查出来问题。请作者帮忙看一下。谢谢。
如果防护之前开启过,你会再执行一次交换操作,但是你并没有把交换后的方法和之前的方法换回来