美文网首页
继承关系中慎用methodswizzle

继承关系中慎用methodswizzle

作者: 氺_氺 | 来源:发表于2021-01-03 09:49 被阅读0次

记录一次在继承关系中遇到methodswizzle坑的经历:

1、在Category中使用runtime的methodswizzle统一为UIButton添加点击延迟的功能:

使用对象关联为UIButton添加延时间隔(cs_acceptEventInterval)和事件触发时间(cs_acceptEventTime)两个运行时的关联属性,

使用methodswizzle用@selector(cs_sendAction:to:forEvent:)替换@selector(sendAction:to:forEvent:),并在@selector(cs_sendAction:to:forEvent:)使用了上述的两个关联属性

2、问题:

UIButton使用一切正常,但是这个category却影响到了UIControl这个控件了,点击UIControl后,会收到

'-[*** cs_acceptEventTime]: unrecognized selector sent to instance 0x10520ce60'

的奔溃信息。

3、原因:

3.1、关联对象添加的两个关联属性作用的是UIButton这个类

3.2、虽然在UIButton的扩展中替换了@selector(sendAction:to:forEvent:),但这个方法是从UIControl中继承过来的,methodswizzle实际上是作用在底层结构体执行的IMP实现,本质上是改了UIControl的@selector(sendAction:to:forEvent:),这种,当UIControl触发事件的时候,运行的是@selector(cs_sendAction:to:forEvent:)这个Selctor的IMP实现,但是UIControl又并没有两个时间属性的对象关联属性,所以这时候就报错了。

4、在UIControl扩展中添加延迟时间的功能,以下代码能正常运行:

#import <UIKit/UIKit.h>

@interfaceUIControl(FixMultiClick)

@property (nonatomic, assign) NSTimeInterval cs_acceptEventInterval; // 重复点击的间隔

@property (nonatomic, assign) NSTimeInterval cs_acceptEventTime;

@end

#import "UIControl+FixMultiClick.h"

#import <objc/runtime.h>

@implementationUIControl(FixMultiClick)

static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";

- (NSTimeInterval)cs_acceptEventInterval {

    return  [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];

}

- (void)setCs_acceptEventInterval:(NSTimeInterval)cs_acceptEventInterval {

    objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(cs_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

static const char *UIControl_acceptEventTime = "UIControl_acceptEventTime";

- (NSTimeInterval)cs_acceptEventTime {

    return  [objc_getAssociatedObject(self, UIControl_acceptEventTime) doubleValue];

}

- (void)setCs_acceptEventTime:(NSTimeInterval)cs_acceptEventTime {

    objc_setAssociatedObject(self, UIControl_acceptEventTime, @(cs_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

// 在load时执行hook

+ (void)load{

    Methodbefore  =class_getInstanceMethod(self,@selector(sendAction:to:forEvent:));

    Methodafter    =class_getInstanceMethod(self,@selector(cs_sendAction:to:forEvent:));

    method_exchangeImplementations(before, after);

}

- (void)cs_sendAction:(SEL)actionto:(id)targetforEvent:(UIEvent*)event {

    if ([NSDate date].timeIntervalSince1970 - self.cs_acceptEventTime < self.cs_acceptEventInterval) {

        DLog(@"___间隔时间太短");

        return;

    }

    if (self.cs_acceptEventInterval > 0) {

        self.cs_acceptEventTime = [NSDate date].timeIntervalSince1970;

    }

    [selfcs_sendAction:actionto:targetforEvent:event];

}

@end

相关文章

  • 继承关系中慎用methodswizzle

    记录一次在继承关系中遇到methodswizzle坑的经历: 1、在Category中使用runtime的meth...

  • 慎用继承

    摘自网络 最近在看大神Casa的文章《跳出面向对象思想(一) 继承》,脑洞大开。文章给我们展示了一个随着产品需求不...

  • Java继承

    继承初步 生活中继承关系 父亲 和 儿子 的关系? 父子关系 第一顺位继承人 代码中的继承关系: 英雄联盟: 所有...

  • MethodSwizzle

    新建工程,注入 Framework后,注入简单测试代码,利用 Runtime 特性交换方法

  • iOS逆向三:代码注入二

    这部分需要对MethodSwizzle有一定了解会用,这里不对MethodSwizzle讨论 对某信静态分析加动态...

  • 使用MethodSwizzle 实现对数组、字典 等系统方法的安

    MethodSwizzle-SafeObject-Keyboard-CFAutoreleasePoolPop-Cr...

  • Java中的继承

    继承 继承的概念: 继承是类与类的一种关系,是一种“is a”的关系 注:Java中的继承是单继承 3. 继承的好...

  • 《Java编程的逻辑》笔记15--初识继承和多态

    继承 继承概念(1)计算机程序经常使用类之间的继承关系来表示对象之间的分类关系(2)在继承关系中,有父类和子类,父...

  • Java入门第二季第三章

    继承 1.继承的概念: 继承是类与类的一种关系,是一种“is a”的关系; 注:java中的继承是单继承; 2.继...

  • 继承

    继承 继承是类与类的关系,是一种“is a”的关系。Java 中的继承为单继承 1. 作用 子类拥有父类的所有属性...

网友评论

      本文标题:继承关系中慎用methodswizzle

      本文链接:https://www.haomeiwen.com/subject/mhkuoktx.html