Object-c 使用objc_property_t runtime机制遍历获取类的所有属性

本文没什么分析之处,需要注意的是,递归查找父类属性,直接给出源码:

#import <Foundation/Foundation.h>

/**
 *  遍历所有类的block(父类)
 */
typedef void (^ClassesEnumeration)(Class c, BOOL *stop);


@interface ClazzAttrMgr : NSObject

+ (void)enumerateClasses:(ClassesEnumeration)enumeration forClazz:(Class) clazz;

+ (NSArray*)getPropertieNamesByObject:(id) obj;

@end

.m文件:记得导入 :#import

//获取类的所有属性名
+ (NSArray*)getPropertieNamesByObject:(id) obj
{
    unsigned int outCount = 0;
    __block NSMutableArray *nameArray = [[NSMutableArray alloc] initWithCapacity:outCount];
    [self enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
        NSLog(@"124------------:%@",c);

        // 获取注册类的属性列表,第一个参数是类,第二个参数是接收类属性数目的变量
        objc_property_t *properties = class_copyPropertyList(c, &outCount);
        //定义一个数组来接收获取的属性名
        //NSMutableArray *nameArray = [[NSMutableArray alloc] initWithCapacity:outCount];
        for (unsigned int i = 0; i < outCount; i++) {
            //通过循环来获取单个属性
            objc_property_t property = properties[i];
            //取得属性名
            NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
            //将得到的属性名放入数组中
            [nameArray addObject:propertyName];

        }
        free(properties);
       // return nameArray;



    } forClazz:[obj class]];
    return nameArray;

    //unsigned int outCount, i;

//    // 获取注册类的属性列表,第一个参数是类,第二个参数是接收类属性数目的变量
//    objc_property_t *properties = class_copyPropertyList([obj class], &outCount);
//    //定义一个数组来接收获取的属性名
//    NSMutableArray *nameArray = [[NSMutableArray alloc] initWithCapacity:outCount];
//    for (i = 0; i < outCount; i++) {
//        //通过循环来获取单个属性
//        objc_property_t property = properties[i];
//        //取得属性名
//        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
//        //将得到的属性名放入数组中
//        [nameArray addObject:propertyName];
//
//    }
//    free(properties);
//    return nameArray;

}

+ (void)enumerateClasses:(ClassesEnumeration)enumeration forClazz:(Class) clazz
{
    // 1.没有block就直接返回
    if (enumeration == nil) return;

    // 2.停止遍历的标记
    BOOL stop = NO;

    // 3.当前正在遍历的类
    Class c = clazz;

    // 4.开始遍历每一个类
    while (c && !stop) {
        // 4.1.执行操作
        enumeration(c, &stop);

        // 4.2.获得父类
        c = class_getSuperclass(c);
        if (c == [NSObject class] || c == [NSManagedObject class]) break;
    }
}


测试父类:

@interface UserParent : NSObject

@property(nonatomic,copy) NSString *parent;

@end

User文件:

typedef enum {
    SexMale,
    SexFemale
} Sex;

@interface User : UserParent
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *icon;
@property (assign, nonatomic) unsigned int age;
@property (copy, nonatomic) NSString *height;
@property (strong, nonatomic) NSNumber *money;
@property (assign, nonatomic) Sex sex;
@property (assign, nonatomic, getter=isGay) BOOL gay;
@end

使用方法:

 NSArray *attrList = [ClazzAttrMgr getPropertieNamesByObject:user];
    NSLog(@"41--------------:%@",attrList);

猜你喜欢

转载自blog.csdn.net/d06110902002/article/details/81134878