事件背景:打算在UIButton的扩展类里面 hook intrinsicContentSize 方法,然后直接在+load的时候调用method_exchangeImplementations把自己的自定义xx_intrinsicContentSize方法跟现有的方法列表里面的交换,然后发生崩溃,但是UILabel就不会。
事件的原因:UIButton并没有重写基类UIView的intrinsicContentSize方法,所以直接把基类UIView的方法和UIButton扩展的方法交换了,当其他UIView的子类调用intrinsicContentSize的时候就会调用到UIButton的xx_intrinsicContentSize扩展方法,但是当前类方法列表肯定是没有的,所以就崩溃了,本质原因是,应该对本类的这方法做hook,不应该hook到基类。UILabel的扩展做同样的事情为什么不会崩溃呢,因为UILabel重写了intrinsicContentSize方法,并不是基类的实现,所以直接替换只是一次对UILabel普通的hook做了一些额外的事情,而且这个hook的方法是在类别里面,可以调得到。
解决办法是:
先调用class_addMethod尝试为当前类UIButton添加intrinsicContentSize方法,class_addMethod这个方法的实现会覆盖父类的方法实现,但不会取代本类中已存在的实现,如果本类中包含一个同名的实现,则函数会返回NO。以保证修改的就是当前类。只要当前类有这个方法,以后对这个类的各种类别+load里面的hook就可以按照Build Phases的顺序hook,做一些自己自定义的额外的事情了。
+ (BOOL)dds_swizzleMethod:(SEL)origSel withMethod:(SEL)altSel
{
Method originMethod = class_getInstanceMethod(self, origSel);
Method newMethod = class_g

在扩展UIButton时尝试hook intrinsicContentSize方法,通过method_exchangeImplementations进行方法交换导致崩溃。原因在于UIButton并未重写此方法,交换导致其他UIView子类调用时找不到正确实现。而UILabel因重写了该方法,故不会崩溃。解决方法是使用class_addMethod尝试为当前类添加intrinsicContentSize方法,确保hook的是本类方法,避免影响父类及其他子类的正常工作。

2394

被折叠的 条评论
为什么被折叠?



