Objective-C - 循环遍历类中的所有属性?

时间:2012-02-12 19:55:02

标签: objective-c properties

是否有办法循环访问对象中的所有属性并获取其“名称”和“值”。

我正在尝试编写一个类别,根据对象的属性名称和值将对象序列化为字符串。我试图阻止为每个类编写编码方法,而是写一个通用的。

这可能吗?

4 个答案:

答案 0 :(得分:23)

您可以使用此代码枚举类中声明的所有属性以及属性的所有属性。我猜你对解析type属性更感兴趣。它们详细here

unsigned int numOfProperties;
objc_property_t *properties = class_copyPropertyList([self class], &numOfProperties);
for ( unsigned int pi = 0; pi < numOfProperties; pi++ ) {
    // Examine the property attributes
    unsigned int numOfAttributes;
    objc_property_attribute_t *propertyAttributes = property_copyAttributeList(properties[pi], &numOfAttributes);
    for ( unsigned int ai = 0; ai < numOfAttributes; ai++ ) {
        switch (propertyAttributes[ai].name[0]) {
            case 'T': // type
                break;
            case 'R': // readonly
                break;
            case 'C': // copy 
                break;
            case '&': // retain
                break;
            case 'N': // nonatomic 
                break;
            case 'G': // custom getter
                break;
            case 'S': // custom setter
                break;
            case 'D': // dynamic 
                break;
            default: 
                break;
        }
    }
    free(propertyAttributes);
}
free(properties);

答案 1 :(得分:2)

我在NSObject上使用以下类别来说明NSLog(@"%@", [someObject propertiesPlease]);,导致日志条目如...

someObject: {
    color = "NSCalibratedRGBColorSpace 0 0 1 1";
    crayon = Blueberry;
}

NSObject的+ Additions.h

@interface NSObject (Additions)
- (NSDictionary *)propertiesPlease;
@end

NSObject的+ Additions.m

@implementation NSObject (Additions)
- (NSDictionary *)propertiesPlease {
NSMutableDictionary *props = [NSMutableDictionary dictionary];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for (i = 0; i < outCount; i++) {
   objc_property_t property = properties[i];
   NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property)];
   id propertyValue = [self valueForKey:(NSString *)propertyName];
   if (propertyValue) [props setObject:propertyValue forKey:propertyName];
}
   free(properties);
   return props;
}
@end

答案 2 :(得分:1)

也许class_copyPropertyList()会做你想做的事情 - 但请注意它只返回声明的属性。

并非所有属性都被声明 - NSDictionaryNSMutableDictionary是类的示例,您可以在其中设置未在类中声明的属性。

docs中的更多内容。

答案 3 :(得分:0)

我还没有评论权限,但要添加@Costique的答案,还有一个额外的属性Type值“V”,它是可以绑定属性的IVar的名称(通过合成)。用这个

可以很容易地发现这一点

@interface Redacted:NSObject

@property(atomic,readonly)int foo;

@end


@implementation Redacted

@synthesize foo = fooBar;

@end

// for all properties
unsigned propertyCount = 0;
objc_property_t *properties = class_copyPropertyList([object class], &propertyCount);
for (int prop = 0; prop < propertyCount; prop++)
{
    // for all property attributes
    unsigned int attributeCount = 0;
    objc_property_attribute_t* attributes = property_copyAttributeList(property, &attributeCount);
    for (unsigned int  attr = 0; attr < attributeCount; attr++)
    {
        NSLog(@"Attribute %d: name: %s, value: %s", attr, attributes[attr].name, attributes[attr].value);
    }
}

2013-07-08 13:47:16.600 Redacted5162:303]属性0:名称:T,值:i

2013-07-08 13:47:16.601编辑[5162:303]属性1:名称:R,值:

2013-07-08 13:47:16.602编辑[5162:303]属性2:名称:V,值:fooBar