List of class properties in Objective-C

前端 未结 6 1947
南方客
南方客 2020-11-29 17:32

Is there a way to get an array of class properties of certain kind? For example if i have interface like this

@interface MyClass : NSObject
    @property (st         


        
6条回答
  •  无人及你
    2020-11-29 17:55

    The answer by @user529758 won't work with ARC and it won't list the properties of any ancestor classes.

    To fix this, you need to traverse up the class hierarchy, and use the ARC-compatible [NSObject valueForKey:] to get the property values.

    Person.h:

    #import 
    
    extern NSMutableArray *propertyNamesOfClass(Class klass);
    
    @interface Person : NSObject
    
    @property (nonatomic) NSString *name;
    
    @end
    

    Person.m:

    #import "Person.h"
    #import 
    
    NSMutableArray *propertyNamesOfClass(Class klass) {
        unsigned int count;
        objc_property_t *properties = class_copyPropertyList(klass, &count);
    
        NSMutableArray *rv = [NSMutableArray array];
    
        for (unsigned int i = 0; i < count; i++)
        {
            objc_property_t property = properties[i];
            NSString *name = [NSString stringWithUTF8String:property_getName(property)];
            [rv addObject:name];
        }
    
        free(properties);
    
        return rv;
    }
    
    @implementation Person
    
    - (NSMutableArray *)allPropertyNames {
        NSMutableArray *classes = [NSMutableArray array];
        Class currentClass = [self class];
        while (currentClass != nil && currentClass != [NSObject class]) {
            [classes addObject:currentClass];
            currentClass = class_getSuperclass(currentClass);
        }
    
        NSMutableArray *names = [NSMutableArray array];
        [classes enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(Class currentClass, NSUInteger idx, BOOL *stop) {
            [names addObjectsFromArray:propertyNamesOfClass(currentClass)];
        }];
    
        return names;
    }
    
    - (NSString*)description {
        NSMutableArray *keys = [self allPropertyNames];
        NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithCapacity:keys.count];
        [keys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
            properties[key] = [self valueForKey:key];
        }];
    
        NSString *className = NSStringFromClass([self class]);
        return [NSString stringWithFormat:@"%@ : %@", className, properties];
    }
    

    Student.h:

    #import "Person.h"
    
    @interface Student : Person
    
    @property (nonatomic) NSString *studentID;
    
    @end
    

    Student.m:

    #import "Student.h"
    
    @implementation Student
    
    @end
    

    main.m:

    #import 
    #import "Student.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            Student *student = [[Student alloc] init];
            student.name = @"John Doe";
            student.studentID = @"123456789";
            NSLog(@"student - %@", student);
        }
        return 0;
    }
    

提交回复
热议问题