iOS开发 Runtime使用大全(二)

本文深入探讨了Objective-C Runtime的高级应用,包括如何利用runtime机制为类动态添加属性及方法交换技术。通过具体示例展示了按钮点击间隔的实现方法,有效防止短时间内多次误触。

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

继续上一篇

2.添加属性

一般情况下,使用Category只能添加方法,不过使用runtime就可以添加属性。

@interface NSObject (Category)
//因为需要运行时添加策略,所以这里不写
@property NSString *name;
@end
#import "NSObject+Category.h"
#import <objc/runtime.h>
@implementation NSObject (Category)

-(void)setName:(NSString *)name{
    //源对象
    //key
    //关联对象
    //关联策略  weak、strong,redonly等
    objc_setAssociatedObject(self, "WenCheng", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSString *)name{
    //返回指定键的关联对象的值
    //self:关联源对象
    //“name”:关联的key
    return objc_getAssociatedObject(self, "WenCheng");
}
@end
3.交换方法
//    得到类的实例方法
//    class_getInstanceMethod

//    得到类的类方法
//    class_getClassMethod

    Method oldMethod = class_getInstanceMethod([self class], @selector(viewWillAppear:));
    Method newMethod = class_getInstanceMethod([self class], @selector(addFind));
//交换
    method_exchangeImplementations(oldMethod, newMethod);

项目中使用

1.按钮点击间隔

创建Category,添加“时间间隔”和“是否可点击”。

@interface UIButton (JC)

@property (nonatomic,assign) NSTimeInterval jc_clickInterval;//添加点击事件的间隔时间

@property (nonatomic, assign) BOOL jc_isIgnoreClick;//是否忽略点击事件,不响应点击事件

@end
static const char *JC_clickInterval = "JC_clickInterval";
static const char *JC_ignoreClick = "JC_ignoreClick";

#pragma mark - 写get和set方法
-(NSTimeInterval)jc_clickInterval{
    return [objc_getAssociatedObject(self, JC_clickInterval) doubleValue];
}

-(void)setJc_clickInterval:(NSTimeInterval)jc_clickInterval{
    objc_setAssociatedObject(self, JC_clickInterval, @(jc_clickInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(BOOL)jc_isIgnoreClick{
    return [objc_getAssociatedObject(self, JC_ignoreClick) boolValue];
}
-(void)setJc_isIgnoreClick:(BOOL)jc_isIgnoreClick{
    objc_setAssociatedObject(self, JC_ignoreClick, @(jc_isIgnoreClick), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - 拦截点击事件
+(void)load{
    Method old = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
    Method new = class_getInstanceMethod(self, @selector(jcSendAction:to:forEvent:));
    method_exchangeImplementations(old, new);
}


#pragma mark - 判断是否可以点击
- (void)jcSendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event{

    if (self.jc_isIgnoreClick) return;
    if (self.jc_clickInterval > 0) {
        self.jc_isIgnoreClick = YES;
        //多少秒后调用方法
        [self performSelector:@selector(setJc_isIgnoreClick:) withObject:@(NO) afterDelay:self.jc_clickInterval];
    }
    //调用原方法
    [self jcSendAction:action to:target forEvent:event];

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值