How do I find all the property keys of a KVC compliant Objective-C object?

11,933

Solution 1

#import "objc/runtime.h"

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);

Solution 2

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.

Solution 3

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 an @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 @propertys and then assuming they're KVO-compliant would be a dangerous choice in my opinion.

Share:
11,933

Related videos on Youtube

armahg
Author by

armahg

Updated on May 22, 2020

Comments

  • armahg
    armahg about 4 years

    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.

  • Mike Abdullah
    Mike Abdullah about 15 years
    Why has somebody modded this down? I'm interested to know what they think is wrong with it.
  • armahg
    armahg about 15 years
    Very useful ... thanks!! I already knew that stringWithCString was deprecated
  • Dale Emery
    Dale Emery over 12 years
    This code gathers only the properties declared directly in the object's class. To get all of the object's properties, you also need to walk the superclass chain and gather those class's properties.
  • chakrit
    chakrit about 12 years
    Where is this method: getPropertyType(property) defined?
  • ipmcc
    ipmcc over 11 years
    This only gets keys declared with the @property syntax. A class may be KVC-compliant for other keyPaths by virtue of implementing complying methods (or method pairs) and/or overriding the core KVC handling methods (i.e. valueForUndefinedKey:, setValue:forUndefinedKey:). There is no way to definitively get the keys that an arbitrary class is KVC-compliant for, unfortunately. Put differently, don't rely on this.
  • Sandy Chapman
    Sandy Chapman about 10 years
    @chakrit he's likely defined a function that parses the result of property_getAttributes to rip out the type name. You can check out this page for more details on this answer and related code.
  • Sandy Chapman
    Sandy Chapman about 10 years
    You might have a point, but this is incredibly useful for CoreData's NSManagedObject derived classes.
  • Mike Abdullah
    Mike Abdullah about 10 years
    OK, but in the specific case of Core Data, NSEntityDescription probably exposes what you care about
  • Sandy Chapman
    Sandy Chapman about 10 years
    You're absolutely right, NSEntityDescription likely is better to use.