ios OC 获取所有属性、变量 class_getProperty class_copyPropertyList class_copyIvarList

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];
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python绿色通道

WePhone创始人自杀后的感想--事缓则圆

主人公据传是快40岁的人,本人又是高智商分子,却在社会经验方面一败涂地。这里简单罗列一下他事情。

12220
来自专栏韩东吉的Unity杂货铺

从象棋到太极,领悟学习之道(二)

维茨金在书中说到,第一点就是要树立一个正确的学习观念,第二点就是要划小圈,听起来可能比较奇怪,什么是划小圈呢?又该如何理解呢?

13030
来自专栏Python绿色通道

因为产品意见不合打架?想多了!

我发现爆料人非常会炒作,本来就是两个人抢微波炉引起的冲突吧,结果说成程序员与产品经理因为产品意见不合而引起的冲突!

18110
来自专栏韩东吉的Unity杂货铺

从象棋到太极,领悟学习之道(三)

前俩节讲述了学习要“树正观”,“划小圈”。那最后的一小节,就来讲述下学习之道的第三点,也是最后一点,建组块。

16550
来自专栏狮乐园

liferay-portlet-container

portlet是portal中最常用的组件了,所以也来山寨一个70版本的portlet container的UI吧。

11230
来自专栏Python绿色通道

到底要不要去培训机构学习?

你花了很短的时间就能去上手一门行业,虽然你花了一些钱,但是你节省了大量的时间和精力,找到了高薪的工作,然后很快就可以把这个款项还上了。

37320
来自专栏Python绿色通道

我要开始写作了

今天是2017年6月30日,这一年已经过半了,而在这半年中我有对生活,对工作有无数强烈的想法充斥于自己的脑海中,有一些想法灵感我会随手去记录,我时常发一些朋友圈...

11820
来自专栏Java架构沉思录

码农晋升为技术管理者后,痛并快乐着的纠结内心

有一个非常有趣的现象:据说大部分的技术管理者,在其从程序员转为管理岗位的时候,都是在领导或公司的要求下,被动的推到管理岗位上的,并非是自己当初有强烈意愿、主动去...

13920
来自专栏韩东吉的Unity杂货铺

从象棋到太极,领悟学习之道(一)

前言里,大致的介绍了一下维茨金的经历,从象棋到太极,在任何人看起来都是两个完全不同的领域,那他又是如何做到在不同的领域里都可以取得骄人的成绩呢?维茨金自己总结到...

12840
来自专栏服务端技术杂谈

方法论

比如一个产品负责人做起事来毫无章法,产品方向随意乱打,这样产品没有方法论,有的是大大的短板,也很难在专业上有长足的进步,项目也往往无疾而终,浪费了团队的粮草子弹...

49140

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励