views:

674

answers:

4

Hello,

Is there a method that returns all the keys for an object conforming to the NSKeyValueCoding protocol?

Something along the lines of [object getPropertyKeys] that would return an NSArray of NSString objects. It would work for any KVC-compliant object. Does such a method exist? I haven't found anything in searching the Apple docs so far.

Thanks, G.

+4  A: 

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];
    const char *propName = property_getName(property);
    if(propName) {
            const char *propType = getPropertyType(property);
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
            ...
    }
}
free(properties);
oxigen
Why has somebody modded this down? I'm interested to know what they think is wrong with it.
Mike Abdullah
Because there was a wrong answer. Before editing ))
oxigen
Yeah. I've withdrawn my downmod. BTW, stringWithCString: is deprecated—use stringWithUTF8String: or stringWithCString:encoding: instead.
Peter Hosey
thanks changed it to stringWithUTF8String
oxigen
Very useful ... thanks!! I already knew that stringWithCString was deprecated
armahg
add #import "objc/runtime.h"
Prairiedogg
+1  A: 

Use class_getPropertyList. That will tell you all the @properties of the object.

It won't necessarily list every KVC-compliant property, because any method that takes no arguments and returns a value is a valid KVC-compliant getter. There's no 100%-reliable way for the runtime to know which ones behave as properties (e.g., -[NSString length]) and which ones behave as commands (e.g., -[NSFileHandle readDataToEndOfFile]).

You should be declaring your KVC-compliant properties as @properties anyway, so this shouldn't be too big of a problem.

Peter Hosey
+1  A: 

There is no such method as the KVO system does not require objects/classes to register with it which properties they support KVO for. Any key could potentially support KVO, the only way to know is from the author's documentation.

And of course, there is no guarantee that a @property will support KVO; it's quite possible to write a property that doesn't (and may be necessary sometimes). So, getting a list of a class's @properties and then assuming they're KVO-compliant would be a dangerous choice in my opinion.

Mike Abdullah
A: 

You need a getPropertyType function. See this post: Get an object attributes list in Objective-C

Chatchavan