class_copyPropertyList
- 看到名字可以看出来他是来获取属性的
- 只能获取到 @property 声明的属性
class_copyIvarList
- 用来获取所有的变量的
- 获取所有的变量,当然包括因 @property 修饰而自动产生的变量 _name
总结
class_copyPropertyList 只能获取到 @property 声明的属性
class_copyIvarList 用来获取所有的变量的
但是以上两个方法都只能获取到当前类的属性和变量(也就是说获取不到父类的属性和变量)
验证
以上的结论通过一段代码可以验证
首先声明类:
@interface KK : NSObject
{
int _i;
}
@property NSString * name;
@property NSString * family;
@end
@implementation KK
- (NSString *)description {
return [NSString stringWithFormat:@"KK -> description: name: %@", self.name];
}
@end
@interface MM : KK
@property int age;
@end
@implementation MM
@end
第一段代码:
KK * k = [[KK alloc] init];
unsigned int a;
objc_property_t * result = class_copyPropertyList(object_getClass(k), &a);
for (unsigned int i = 0; i < a; i++) {
objc_property_t o_t = result[i];
NSLog(@"%@", [NSString stringWithFormat:@"%s", property_getName(o_t)]);
}
free(result);
Ivar * iv = class_copyIvarList(object_getClass(k), &a);
for (unsigned int i = 0; i < a; i++) {
Ivar i_v = iv[i];
NSLog(@"%@", [NSString stringWithFormat:@"%s", ivar_getName(i_v)]);
}
free(iv);
2018-06-07 14:19:25.184787+0800 runtime[16059:422758] name
2018-06-07 14:19:25.184884+0800 runtime[16059:422758] family
2018-06-07 14:19:25.184940+0800 runtime[16059:422758] _i
2018-06-07 14:19:25.184960+0800 runtime[16059:422758] _name
2018-06-07 14:19:25.184977+0800 runtime[16059:422758] _family
如上可以验证
- class_copyPropertyList 只能获取 @property 修饰的属性
第二段代码
KK * k = [[MM alloc] init];
unsigned int a;
objc_property_t * result = class_copyPropertyList(object_getClass(k), &a);
for (unsigned int i = 0; i < a; i++) {
objc_property_t o_t = result[i];
NSLog(@"%@", [NSString stringWithFormat:@"%s", property_getName(o_t)]);
}
free(result);
Ivar * iv = class_copyIvarList(object_getClass(k), &a);
for (unsigned int i = 0; i < a; i++) {
Ivar i_v = iv[i];
NSLog(@"%@", [NSString stringWithFormat:@"%s", ivar_getName(i_v)]);
}
free(iv);
2018-06-07 14:21:26.258232+0800 runtime[16089:423658] age
2018-06-07 14:21:26.258295+0800 runtime[16089:423658] _age
- 只获取当前类的属性和方法
获取指定类的属性以及父类的所有属性
/**
获取指定类的属性
@param cls 被获取属性的类
@return 属性名称 [NSString *]
*/
NSArray * getClassProperty(Class cls) {
if (!cls) return @[];
NSMutableArray * all_p = [NSMutableArray array];
unsigned int a;
objc_property_t * result = class_copyPropertyList(cls, &a);
for (unsigned int i = 0; i < a; i++) {
objc_property_t o_t = result[i];
[all_p addObject:[NSString stringWithFormat:@"%s", property_getName(o_t)]];
}
free(result);
return [all_p copy];
}
/**
获取指定类(以及其父类)的所有属性
@param cls 被获取属性的类
@param until_class 当查找到此类时会停止查找,当设置为 nil 时,默认采用 [NSObject class]
@return 属性名称 [NSString *]
*/
NSArray * getAllProperty(Class cls, Class until_class) {
Class stop_class = until_class ?: [NSObject class];
if (class_getSuperclass(cls) == stop_class) return @[];
NSMutableArray * all_p = [NSMutableArray array];
[all_p addObjectsFromArray:getClassProperty(cls)];
if (class_getSuperclass(cls) == stop_class) {
return [all_p copy];
} else {
[all_p addObjectsFromArray:getAllProperty([cls superclass], stop_class)];
}
return [all_p copy];
}
获取指定类以及其父类所有的变量
/**
获取指定类的变量
@param cls 被获取变量的类
@return 变量名称集合 [NSString *]
*/
NSArray * getClassIvar(Class cls) {
if (!cls) return @[];
NSMutableArray * all_p = [NSMutableArray array];
unsigned int a;
Ivar * iv = class_copyIvarList(cls, &a);
for (unsigned int i = 0; i < a; i++) {
Ivar i_v = iv[i];
[all_p addObject:[NSString stringWithFormat:@"%s", ivar_getName(i_v)]];
}
free(iv);
return [all_p copy];
}
/**
获取指定类(以及其父类)的所有变量
@param cls 被获取变量的类
@param until_class 当查找到此类时会停止查找,当设置为 nil 时,默认采用 [NSObject class]
@return 变量名称集合 [NSString *]
*/
NSArray * getAllIvar(Class cls, Class until_class) {
Class stop_class = until_class ?: [NSObject class];
if (class_getSuperclass(cls) == stop_class) return @[];
NSMutableArray * all_p = [NSMutableArray array];
[all_p addObjectsFromArray:getClassIvar(cls)];
if (class_getSuperclass(cls) == stop_class) {
return [all_p copy];
} else {
[all_p addObjectsFromArray:getAllIvar([cls superclass], stop_class)];
}
return [all_p copy];
}