继续上一篇
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];
}