1

I want to use reflection to get all the properties of a ViewController, that are subclasses of UIView.

I have this method to get all the properties:

unsigned count;
objc_property_t *properties = class_copyPropertyList([self class], &count);

NSMutableArray *rv = [NSMutableArray array];

unsigned i;
for (i = 0; i < count; i++)
{
    objc_property_t property = properties[i];

    NSString *name = [NSString stringWithUTF8String:property_getName(property)];
    [rv addObject:name];
}

free(properties);

But how do I find which type this property is?

Nayan
  • 3,014
  • 2
  • 17
  • 33
Lena Bru
  • 13,521
  • 11
  • 61
  • 126

2 Answers2

1

You can find type via:

 const char * propertyAttrs = property_getAttributes(property);

The output will be like the following:

(lldb) p propertyAttrs
(const char *) $2 = 0x0065f74d "T@"UICollectionView",W,N,V_collectionView"

Where "T@"UICollectionView" is property type.

UPDATE

I've played with it. This code is not ideal and not tested well, but it works:

const char * property_getTypeString( objc_property_t property )
{
    const char * attrs = property_getAttributes( property );
    if ( attrs == NULL )
        return ( NULL );

    static char buffer[256];
    const char * e = strchr( attrs, ',' );
    if ( e == NULL )
        return ( NULL );

    int len = (int)(e - attrs);
    memcpy( buffer, attrs, len );
    buffer[len] = '\0';

    return ( buffer );
}


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    unsigned count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);

    NSMutableArray *rv = [NSMutableArray array];

    unsigned i;
    for (i = 0; i < count; i++)
    {
        objc_property_t property = properties[i];

        NSString *name = [NSString stringWithUTF8String:property_getName(property)];

        const char * typeString = property_getTypeString(property);

        NSString *type = [NSString stringWithUTF8String:typeString];

        NSCharacterSet *delimiters = [NSCharacterSet characterSetWithCharactersInString:@"\""];
        NSArray *splitString = [type componentsSeparatedByCharactersInSet:delimiters];

        Class classType = NSClassFromString(splitString[1]);

        BOOL result = [classType isSubclassOfClass:UIView.class];

        [rv addObject:name];
    }

    free(properties);

}

The function property_getTypeString is borrowed from here: https://github.com/AlanQuatermain/aqtoolkit

Sergey Demchenko
  • 2,924
  • 1
  • 24
  • 26
  • what does this line mean (const char *) $2 = 0x0065f74d "T@"UICollectionView",W,N,V_collectionView" – Lena Bru Jan 16 '14 at 09:04
  • you are missing : "if(result) then add to array" in the line before last, but indeed this does the job, thank you! – Lena Bru Jan 20 '14 at 07:41
  • how can i set an attribute to these properties, so that later i can use this attribute without reflection ? – Lena Bru Jan 20 '14 at 07:54
0

Maybe you can check runtime.h property_getAttributes(property_name)

as an example:

 // will return what type the property is
  const char * propertyAttrs = property_getAttributes(property);
Joshua
  • 2,432
  • 1
  • 20
  • 29
  • i can get the attributes, but how do i determine that the property i am looking at is a subclass of UIView ? – Lena Bru Jan 16 '14 at 09:03
  • in your case the property result will be like (const char *) propertyAttrs = 0x00007985 "T@"UIView",&,N,V_thisPropertySix" as you can see it specify the property is a UIView – Joshua Jan 16 '14 at 09:05
  • so i just check if this property has the string "UIView" in it ? what if this is a UIButton or a UILabel ? which are subclasses of UIView ? – Lena Bru Jan 16 '14 at 09:06
  • yup it will still be able to show if its a UIButton or a UILabel. have a try and see – Joshua Jan 16 '14 at 09:58