iOS Runtime获取类成员变量,属性,方法等

1,378 阅读1分钟

本文主要写通过Runtime获取类成员变量,属性,方法等的基础用法。

测试类

先写一个测试类,如下:

@interface Test()
{
    int s;                          //成员变量
}
@property(nonatomic, strong)NSString *str;  //属性
@end
@implementation Test

- (NSString *)str {                 //方法
    return @"str";
}

- (void)setStr:(NSString *)str {}   //方法

- (void)test {                      //方法
    printf("test in main\n");
}
+ (void)test2022 {}                 //类方法
@end

获取类成员变量

通过RuntimeAPI class_copyIvarList 来获取类的成员变量列表。Test类只有一个成员变量就是sproperty定义的str 因为自己实现了 getset 所以没有产生成员变量 _str

unsigned int ivarCount;
Class class =  Test.class;
Ivar *ivarList = class_copyIvarList(class, &ivarCount);
for (unsigned int i = 0; i < ivarCount; i++) {
    Ivar myIvar = ivarList[i];
    const char *ivarName = ivar_getName(myIvar);
    NSLog(@"%@ ivar(%d) : %s", class, i, ivarName);
}
free(ivarList);

image.png

获取类的属性

通过RuntimeAPI class_copyPropertyList 来获取类的属性列表。Test类只有一个属性就是str

unsigned int propertyCount;
Class class = Test.class;
objc_property_t *propertyList = class_copyPropertyList(class, &propertyCount);
for (unsigned int i = 0; i < propertyCount; i++) {
    const char *propertyName = property_getName(propertyList[i]);
    NSLog(@"%@ propertyName(%d) : %s", class, i, propertyName);
}
free(propertyList);

image.png

获取类的方法列表

通过RuntimeAPI class_copyMethodList 来获取类的方法列表。

unsigned int methodCount;
Class class = Test.class;
Method *methodList = class_copyMethodList(class, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
    Method method = methodList[i];
    NSLog(@"%@ method(%d) : %@", class, i, NSStringFromSelector(method_getName(method)));
}
free(methodList);

image.png

获取类的协议列表

通过RuntimeAPI class_copyProtocolList 来获取类的协议列表。因为Test类并没有实现什么协议,这里用的NSObject

unsigned int protocolCount;
Class class = NSObject.class;
__unsafe_unretained Protocol **protocolList = class_copyProtocolList(class, &protocolCount);
for (unsigned int i = 0; i < protocolCount; i++) {
    Protocol *myProtocal = protocolList[i];
    const char *protocolName = protocol_getName(myProtocal);
    NSLog(@"%@ protocol(%d) : %s", class, i, protocolName);
}
free(protocolList);

image.png

获取类的类方法

获取类的类方法,使用的同样是RuntimeAPI class_copyMethodList。只不类方法存储在元类上,通过object_getClass获取到类的元类,就可以发现类方法了。

unsigned int methodCount;
Class class = object_getClass(Test.class);
Method *methodList = class_copyMethodList(class, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
    Method method = methodList[i];
    NSLog(@"%@ method(%d) : %@", class, i, NSStringFromSelector(method_getName(method)));
}
free(methodList);

image.png