Getting a list of class properties in iOS

I am trying to get a list of all the properties that define my class or any of its subclasses. The next code snippet is the code that I used, and it worked properly until the recent beta version of iOS8.

if(!dictionary) { dictionary = [NSMutableDictionary dictionary]; // Get all properties we have until we hit CBLNestedModel while(klass != [CBLNestedModel class]) { unsigned count; objc_property_t* properties = class_copyPropertyList(klass, &count); for (unsigned i = 0; i < count; i++) { objc_property_t property = properties[i]; const char* propertyNameC = property_getName(property); NSString* propertyName = [NSString stringWithUTF8String:propertyNameC]; const char* propertyAttrC = property_getAttributes(property); NSString* propertyAttrS = [NSString stringWithUTF8String:propertyAttrC]; NSArray* propertyAttr = [propertyAttrS componentsSeparatedByString:@","]; NSLog(@"%@ has property %@", NSStringFromClass(klass), propertyName); dictionary[propertyName] = propertyAttr; } free(properties); klass = [klass superclass]; } propertyDictionary[klassString] = dictionary; } 

CBLNestedModel comes from NSObject. Basically, I want all the properties declared by any subclass of CBLNestedModel, or its subclasses. The problem I am facing is that now this code returns extraneous properties that are not defined in my subclasses. PropertyNames are returned using @"superclass", @"description", @"debugDescription", @"hash" for specific classes, although I never defined these properties anywhere in my subclasses,

It is strange that these extraneous properties are not returned for all subclasses of CBLNestedModel, but only for specific subclasses. However, they will be reliably returned for these subclasses each time my application starts.

Any idea why this is happening now?

+6
source share
2 answers

Are your CBLNestedModel subclasses CBLNestedModel to any protocols? I used to see a similar problem with the object I had, and I could not understand why hash , description , superclass and debugDescription , and I finally figured it out. Here is what I had:

 @interface FOOObject : NSObject<NSCopying, FOOOtherProtocol> 

Looks great, it was a direct subclass of NSObject . In fact, I had other objects to test: one with properties and one without.

 @interface FOOObjectWithProperties : NSObject @property NSString *someProperty; @end 

and

 @interface FOOObjectWithoutProperties : NSObject @end 

During the FOOObjectWithProperties and FOOObjectWithoutProperties both parameters did not have the four above-mentioned NSObject properties, but the original FOOObject DID .

So what is the difference? If you look at NSCopying , it did not add any properties, so I looked at FOOOtherProtocol , some protocol that I implemented, and it did not have any declared properties.

BUT

Look at the FOOOtherProtocol ad:

 @protocol FOOOtherProtocol<NSObject> 

THIS IS THIS . The objective-c runtime DOES NOT include the properties of the superclass in that it returns, but will include the properties declared in protocol extensions (protocols that force other protocols to adhere).

Pay attention to hash , description , superclass and debugDescription ?

See where they are declared in the NSObject protocol declaration

Remove the forced execution of the NSObject protocol from your subclasses (since they are subclasses of NSObject anyway that already match it), and you should see that these properties go away.

+9
source

It appears that in iOS 8, these 4 methods are now declared read-only properties in NSObject.

More info here .

+1
source

Source: https://habr.com/ru/post/972609/


All Articles