Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C 2.0: class_copyPropertyList(), how to list properties from categories

I tried to list all properties of an Objective-C class like described in the Objective-C 2.0 Runtime Programming Guide:

id LenderClass = objc_getClass("UIView");
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
for (i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}

But this lists only three properties:

userInteractionEnabled Tc,GisUserInteractionEnabled
layer T@"CALayer",R,&,V_layer
tag Ti,V_tag

Looking at the header file for UIView.h those are the three properties directly declared in the class. The other UIView properties are added through categories.

How do I get all properties of a class, including those coming from categories?

I tried this with the iPhone simulator (iPhone SDK 2.2.1), btw. (in case this is important).

like image 829
ashcatch Avatar asked May 11 '09 15:05

ashcatch


1 Answers

Based on my tests here, properties from categories will show up when using class_copyPropertyList. It looks as though the properties you're seeing on UIView are only described as properties in the public headers, not actually declared as such when building the UIKit itself. Probably they adopted the property syntax to make the creation of the public headers a little quicker.

For reference, here's my test project:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface TestClass : NSObject
{
    NSString * str1;
    NSString * str2;
}
@property (nonatomic, copy) NSString * str1;
@end

@interface TestClass (TestCategory)
@property (nonatomic, copy) NSString * str2;
@end

@implementation TestClass
@synthesize str1;
@end

@implementation TestClass (TestCategory)

// have to actually *implement* these functions, can't use @synthesize for category-based properties
- (NSString *) str2
{
    return ( str2 );
}

- (void) setStr2: (NSString *) newStr
{
    [str2 release];
    str2 = [newStr copy];
}

@end

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([TestClass class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
    }

    [pool drain];
    return 0;
}

And here's the output:

str2 T@"NSString",C
str1 T@"NSString",C,Vstr1
like image 135
Jim Dovey Avatar answered Sep 20 '22 12:09

Jim Dovey