objective-c - iOS 获取属性类

标签 objective-c ios properties

我正在尝试获取未知类的所有属性以及每个属性的类的列表。现在我得到了一个对象的所有属性的列表(我递归地做它以获得所有的父类(super class))。我的灵感来自 this post

+ (NSArray *)classPropsFor:(Class)klass
{    
    NSLog(@"Properties for class:%@", klass);
    if (klass == NULL || klass == [NSObject class]) {
        return nil;
    }

    NSMutableArray *results = [[NSMutableArray alloc] init];

    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(klass, &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if(propName) {
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            [results addObject:propertyName];
        }
        NSArray* dict = [self classPropsFor:[klass superclass]];
        [results addObjectsFromArray:dict];
    }
    free(properties);

    return [NSArray arrayWithArray:results];
}

所以现在我想要每个属性的类,我这样做:

NSArray* properties = [PropertyUtil classPropsFor:[self class]];
for (NSString* property in properties) {
    id value= [self valueForKey:property];
    NSLog(@"Value class for key: %@ is %@", property, [value class]);
}

问题是它适用于 NSStrings 或不适用于自定义类,因为它返回 null。我想递归地创建一个字典来表示一个对象,该对象内部可以包含其他对象,而且我认为我需要知道每个属性的类,这可能吗?

最佳答案

为此做了一个小方法。

// Simple as.
Class propertyClass = [customObject classOfPropertyNamed:propertyName];

可以在很多方面进行优化,但我喜欢它。


实现过程如下:

-(Class)classOfPropertyNamed:(NSString*) propertyName
{
    // Get Class of property to be populated.
    Class propertyClass = nil;
    objc_property_t property = class_getProperty([self class], [propertyName UTF8String]);
    NSString *propertyAttributes = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding];
    NSArray *splitPropertyAttributes = [propertyAttributes componentsSeparatedByString:@","];
    if (splitPropertyAttributes.count > 0)
    {
        // xcdoc://ios//library/prerelease/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
        NSString *encodeType = splitPropertyAttributes[0];
        NSArray *splitEncodeType = [encodeType componentsSeparatedByString:@"\""];
        NSString *className = splitEncodeType[1];
        propertyClass = NSClassFromString(className);
    }
    return propertyClass;
}

它是 eppz!kit 的一部分,在一个名为 NSObject+EPPZRepresentable.h 的开发对象表示中.它实际上完成了您最初要实现的目标。

// Works vica-versa.
NSDictionary *representation = [customObject dictionaryRepresentation];
CustomClass = [CustomClass representableWithDictionaryRepresentation:representation];

它编码多种类型,遍历集合,表示 CoreGraphics 类型、UIColors,还表示/重构对象引用。


新版本甚至会吐出 C 类型名称命名结构类型:

NSLog(@"%@", [self typeOfPropertyNamed:@"index"]); // unsigned int
NSLog(@"%@", [self typeOfPropertyNamed:@"area"]); // CGRect
NSLog(@"%@", [self typeOfPropertyNamed:@"keyColor"]); // UIColor

eppz!model的一部分,随时使用 https://github.com/eppz/eppz.model/blob/master/eppz!model/NSObject%2BEPPZModel_inspecting.m#L111 的方法实现

关于objective-c - iOS 获取属性类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10687039/

相关文章:

Objective-C:从类引用创建实例

iphone - 使用 Core Data 图像填充 tableView

ios - 使用 Swift 将 UIImage 直接添加到 FBSDKShareLinkContent 中?

python - 无法在马尔可夫政权切换模型中的属性类中设置属性

php - PHP中的类继承问题

ios - SalesforceSDKManager 的自定义登录域

iphone - iPhone 上的 SQLite 表无效?

ios - 使用 Xcode 6 和 Swift 语言点击 uibutton 上的 exc_bad_access

iphone - UIScrollView通知?

properties - OWL:为什么数据属性不能是 InverseFunctionalProperty?