struct objc_class {
Class isa;//指针,顾名思义,表示是一个什么,
//实例的isa指向类对象,类对象的isa指向元类
#if !__OBJC2__
Class super_class; //指向父类
const char *name; //类名
long version;
long info;
long instance_size
struct objc_ivar_list *ivars //成员变量列表
struct objc_method_list **methodLists; //方法列表
struct objc_cache *cache;//缓存
//一种优化,调用过的方法存入缓存列表,下次调用先找缓存
struct objc_protocol_list *protocols //协议列表
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
#import <objc/runtime.h>
// 输出类的一些信息
- (void)logInfo {
unsigned int count;// 用于记录列表内的数量,进行循环输出
// 获取属性列表
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (unsigned int i = 0; i < count; i++) {
const char *propertyName = property_getName(propertyList[i]);
NSLog(@"property --> %@", [NSString stringWithUTF8String:propertyName]);
}
// 获取方法列表
Method *methodList = class_copyMethodList([self class], &count);
for (unsigned int i; i < count; i++) {
Method method = methodList[i];
NSLog(@"method --> %@", NSStringFromSelector(method_getName(method)));
}
// 获取成员变量列表
Ivar *ivarList = class_copyIvarList([self class], &count);
for (unsigned int i; i < count; i++) {
Ivar myIvar = ivarList[i];
const char *ivarName = ivar_getName(myIvar);
NSLog(@"Ivar --> %@", [NSString stringWithUTF8String:ivarName]);
}
// 获取协议列表
__unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);
for (unsigned int i; i < count; i++) {
Protocol *myProtocal = protocolList[i];
const char *protocolName = protocol_getName(myProtocal);
NSLog(@"protocol --> %@", [NSString stringWithUTF8String:protocolName]);
}
}
// 调用不存在的类方法时触发,默认返回NO,可以加上自己的处理后返回YES + (BOOL)resolveClassMethod:(SEL)sel; // 调用不存在的实例方法时触发,默认返回NO,可以加上自己的处理后返回YES + (BOOL)resolveInstanceMethod:(SEL)sel; // 将调用的不存在的方法重定向到一个其他声明了这个方法的类里去,返回那个类的target - (id)forwardingTargetForSelector:(SEL)aSelector; // 将调用的不存在的方法打包成 NSInvocation 给你,自己处理后调用 invokeWithTarget: 方法让某个类来触发 - (void)forwardInvocation:(NSInvocation *)anInvocation;
@interface ViewController ()
@property (nonatomic, strong) UIButton *logBtn;
- (void)notHas;// 要调用的实例方法,没有具体实现
@end
- (void)viewDidLoad {
[super viewDidLoad];
// 添加按钮
self.logBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 100, 20)];
[self.logBtn setTitle:@"测 试" forState:UIControlStateNormal];
[self.logBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
// 添加没有实现的点击事件
[self.logBtn addTarget:self action:@selector(notHas) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.logBtn];
}
// 拦截对不存在的方法的调用
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSLog(@"notFind!");
// 给本类动态添加一个方法
if ([NSStringFromSelector(sel) isEqualToString:@"notHas"]) {
class_addMethod(self, sel, (IMP)runAddMethod, "v@:*");
}
// 注意要返回YES
return YES;
}
// 要动态添加的方法,这是一个C方法
void runAddMethod(id self, SEL _cmd, NSString *string) {
NSLog(@"动态添加一个方法来提示");
}
// 关联对象 static char associatedObjectKey; objc_setAssociatedObject(self, &associatedObjectKey, @"我就是要关联的字符串对象内容", OBJC_ASSOCIATION_RETAIN_NONATOMIC); NSString *theString = objc_getAssociatedObject(self, &associatedObjectKey); NSLog(@"关联对象:%@", theString);
enum {
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
};
//添加关联对象
- (void)addAssociatedObject:(id)object{
objc_setAssociatedObject(self, @selector(getAssociatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//获取关联对象
- (id)getAssociatedObject{
return objc_getAssociatedObject(self, _cmd);
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-3 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2026 源码网商城 (www.yuanmawang.com) 版权所有