使用反射的属性类型或类

Arn*_*ein 13 reflection introspection objective-c deserialization

我想知道是否可以确定Objects属性的类或基本类型.获取所有属性名称和值非常简单.所以回答

那么有什么方法可以获得属性类类型,而属性没有值或零值?

示例代码

@interface MyObject : NSObject
@property (nonatomic, copy) NSString *aString;
@property (nonatomic, copy) NSDate *aDate;
@property                   NSInteger aPrimitive;
@end

@implementation MyObject
@synthesize aString;
@synthesize aDate;
@synthesize aPrimitive;

- (void)getTheTypesOfMyProperties {
    unsigned int count;
    objc_property_t* props = class_copyPropertyList([self class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = props[i];

        // Here I can easy get the name or value
        const char * name = property_getName(property);

        // But is there any magic function that can tell me the type?
        // the property can be nil at this time
        Class cls = magicFunction(property);
    }
    free(props);
}

@end
Run Code Online (Sandbox Code Playgroud)

Arn*_*ein 34

在搜索了关于objc Runtime的Apples文档后,根据这个SO答案我终于得到了它的工作.我只是想分享我的结果.

unsigned int count;
objc_property_t* props = class_copyPropertyList([MyObject class], &count);
for (int i = 0; i < count; i++) {
    objc_property_t property = props[i];
    const char * name = property_getName(property);
    NSString *propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
    const char * type = property_getAttributes(property);
    NSString *attr = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];

    NSString * typeString = [NSString stringWithUTF8String:type];
    NSArray * attributes = [typeString componentsSeparatedByString:@","];
    NSString * typeAttribute = [attributes objectAtIndex:0];
    NSString * propertyType = [typeAttribute substringFromIndex:1];
    const char * rawPropertyType = [propertyType UTF8String];

    if (strcmp(rawPropertyType, @encode(float)) == 0) {
        //it's a float
    } else if (strcmp(rawPropertyType, @encode(int)) == 0) {
        //it's an int
    } else if (strcmp(rawPropertyType, @encode(id)) == 0) {
        //it's some sort of object
    } else {
        // According to Apples Documentation you can determine the corresponding encoding values
    }

    if ([typeAttribute hasPrefix:@"T@"]) {
        NSString * typeClassName = [typeAttribute substringWithRange:NSMakeRange(3, [typeAttribute length]-4)];  //turns @"NSDate" into NSDate
        Class typeClass = NSClassFromString(typeClassName);
        if (typeClass != nil) {
            // Here is the corresponding class even for nil values
        }
    }

}
free(props);
Run Code Online (Sandbox Code Playgroud)

  • 这是一件非常高兴的事情,我很高兴找到您的答案!这对于将bulsh * t解析为ObjC类非常好,例如,当API人员决定将所有内容都以字符串形式发送时: (2认同)
  • 这有一个棘手的id类型错误 - id属性的编码只是"T @",所以它将通过最后一次if检查,但[typeAttribute length] -4将是负数,事情会爆炸. (2认同)